udp6.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. /**
  2. * Copyright (c) 2014 - 2019, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. #include "nordic_common.h"
  41. #include "sdk_common.h"
  42. #include "sdk_config.h"
  43. #include "iot_common.h"
  44. #include "iot_pbuffer.h"
  45. #include "udp_api.h"
  46. #include "udp.h"
  47. #include "ipv6_utils.h"
  48. #if UDP6_CONFIG_LOG_ENABLED
  49. #define NRF_LOG_MODULE_NAME udp6
  50. #define NRF_LOG_LEVEL UDP6_CONFIG_LOG_LEVEL
  51. #define NRF_LOG_INFO_COLOR UDP6_CONFIG_INFO_COLOR
  52. #define NRF_LOG_DEBUG_COLOR UDP6_CONFIG_DEBUG_COLOR
  53. #include "nrf_log.h"
  54. NRF_LOG_MODULE_REGISTER();
  55. #define UDP6_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
  56. #define UDP6_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
  57. #define UDP6_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
  58. #define UDP6_ENTRY() UDP6_TRC(">> %s", __func__)
  59. #define UDP6_EXIT() UDP6_TRC("<< %s", __func__)
  60. #else // UDP6_CONFIG_LOG_ENABLED
  61. #define UDP6_TRC(...) /**< Disables traces. */
  62. #define UDP6_DUMP(...) /**< Disables dumping of octet streams. */
  63. #define UDP6_ERR(...) /**< Disables error logs. */
  64. #define UDP6_ENTRY(...)
  65. #define UDP6_EXIT(...)
  66. #endif // UDP6_CONFIG_LOG_ENABLED
  67. /**
  68. * @defgroup api_param_check API Parameters check macros.
  69. *
  70. * @details Macros that verify parameters passed to the module in the APIs. These macros
  71. * could be mapped to nothing in final versions of code to save execution and size.
  72. * UDP_DISABLE_API_PARAM_CHECK should be set to 1 to disable these checks.
  73. *
  74. * @{
  75. */
  76. #if (UDP6_DISABLE_API_PARAM_CHECK == 0)
  77. /**@brief Macro to check is module is initialized before requesting one of the module procedures. */
  78. #define VERIFY_MODULE_IS_INITIALIZED() \
  79. if (m_initialization_state == false) \
  80. { \
  81. return (SDK_ERR_MODULE_NOT_INITIALIZED | IOT_UDP6_ERR_BASE); \
  82. }
  83. /**@brief Macro to check is module is initialized before requesting one of the module
  84. procedures but does not use any return code. */
  85. #define VERIFY_MODULE_IS_INITIALIZED_VOID() \
  86. if (m_initialization_state == false) \
  87. { \
  88. return; \
  89. }
  90. /**
  91. * @brief Verify NULL parameters are not passed to API by application.
  92. */
  93. #define NULL_PARAM_CHECK(PARAM) \
  94. if ((PARAM) == NULL) \
  95. { \
  96. return (NRF_ERROR_NULL | IOT_UDP6_ERR_BASE); \
  97. }
  98. /**
  99. * @brief Verify socket id passed on the API by application is valid.
  100. */
  101. #define VERIFY_SOCKET_ID(ID) \
  102. if (((ID) >= UDP6_MAX_SOCKET_COUNT)) \
  103. { \
  104. return (NRF_ERROR_INVALID_ADDR | IOT_UDP6_ERR_BASE); \
  105. }
  106. /**
  107. * @brief Verify socket id passed on the API by application is valid.
  108. */
  109. #define VERIFY_PORT_NUMBER(PORT) \
  110. if ((PORT) == 0) \
  111. { \
  112. return (NRF_ERROR_INVALID_PARAM | IOT_UDP6_ERR_BASE); \
  113. }
  114. /**
  115. * @brief Verify socket id passed on the API by application is valid.
  116. */
  117. #define VERIFY_NON_ZERO_LENGTH(LEN) \
  118. if ((LEN) == 0) \
  119. { \
  120. return (NRF_ERROR_INVALID_LENGTH | IOT_UDP6_ERR_BASE); \
  121. }
  122. #else // UDP6_DISABLE_API_PARAM_CHECK
  123. #define VERIFY_MODULE_IS_INITIALIZED()
  124. #define VERIFY_MODULE_IS_INITIALIZED_VOID()
  125. #define NULL_PARAM_CHECK(PARAM)
  126. #define VERIFY_SOCKET_ID(ID)
  127. #endif //UDP6_DISABLE_API_PARAM_CHECK
  128. /**
  129. * @defgroup ble_ipsp_mutex_lock_unlock Module's Mutex Lock/Unlock Macros.
  130. *
  131. * @details Macros used to lock and unlock modules. Currently, SDK does not use mutexes but
  132. * framework is provided in case need arises to use an alternative architecture.
  133. * @{
  134. */
  135. #define UDP_MUTEX_LOCK() SDK_MUTEX_LOCK(m_udp_mutex) /**< Lock module using mutex */
  136. #define UDP_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_udp_mutex) /**< Unlock module using mutex */
  137. /** @} */
  138. #define UDP_PORT_FREE 0 /**< Reserved port of the socket, indicates that port is free. */
  139. /**@brief UDP Socket Data needed by the module to manage it. */
  140. typedef struct
  141. {
  142. uint16_t local_port; /**< Local Port of the socket. */
  143. uint16_t remote_port; /**< Remote port of the socket. */
  144. ipv6_addr_t local_addr; /**< Local IPv6 Address of the socket. */
  145. ipv6_addr_t remote_addr; /**< Remote IPv6 Address of the socket. */
  146. udp6_handler_t rx_cb; /**< Callback registered by application to receive data on the socket. */
  147. void * p_app_data; /**< Application data mapped to the socket using the udp6_app_data_set. */
  148. } udp_socket_entry_t;
  149. SDK_MUTEX_DEFINE(m_udp_mutex) /**< Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */
  150. static bool m_initialization_state = false; /**< Variable to maintain module initialization state. */
  151. static udp_socket_entry_t m_socket[UDP6_MAX_SOCKET_COUNT]; /**< Table of sockets managed by the module. */
  152. /** @brief Initializes socket managed by the module. */
  153. static void udp_socket_init(udp_socket_entry_t * p_socket)
  154. {
  155. p_socket->local_port = UDP_PORT_FREE;
  156. p_socket->remote_port = UDP_PORT_FREE;
  157. p_socket->rx_cb = NULL;
  158. p_socket->p_app_data = NULL;
  159. IPV6_ADDRESS_INITIALIZE(&p_socket->local_addr);
  160. IPV6_ADDRESS_INITIALIZE(&p_socket->remote_addr);
  161. }
  162. /**
  163. * @brief Find UDP socket based on local port. If found its index to m_socket table is returned.
  164. * else UDP6_MAX_SOCKET_COUNT is returned.
  165. */
  166. static uint32_t socket_find(uint16_t port)
  167. {
  168. uint32_t index;
  169. for (index = 0; index < UDP6_MAX_SOCKET_COUNT; index++)
  170. {
  171. if (m_socket[index].local_port == port)
  172. {
  173. break;
  174. }
  175. }
  176. return index;
  177. }
  178. uint32_t udp_init(void)
  179. {
  180. uint32_t index;
  181. UDP6_ENTRY();
  182. SDK_MUTEX_INIT(m_udp_mutex);
  183. UDP_MUTEX_LOCK();
  184. for (index = 0; index < UDP6_MAX_SOCKET_COUNT; index++)
  185. {
  186. udp_socket_init(&m_socket[index]);
  187. }
  188. m_initialization_state = true;
  189. UDP6_EXIT();
  190. UDP_MUTEX_UNLOCK();
  191. return NRF_SUCCESS;
  192. }
  193. uint32_t udp6_socket_allocate(udp6_socket_t * p_socket)
  194. {
  195. VERIFY_MODULE_IS_INITIALIZED();
  196. NULL_PARAM_CHECK(p_socket);
  197. UDP6_ENTRY();
  198. UDP_MUTEX_LOCK();
  199. //Search for an unassigned socket.
  200. const uint32_t socket_id = socket_find(UDP_PORT_FREE);
  201. uint32_t err_code = NRF_SUCCESS;
  202. if (socket_id != UDP6_MAX_SOCKET_COUNT)
  203. {
  204. UDP6_TRC("Assigned socket 0x%08lX", socket_id);
  205. // Found a free socket. Assign.
  206. p_socket->socket_id = socket_id;
  207. }
  208. else
  209. {
  210. // No free socket found.
  211. UDP6_ERR("No room for new socket.");
  212. err_code = (NRF_ERROR_NO_MEM | IOT_UDP6_ERR_BASE);
  213. }
  214. UDP_MUTEX_UNLOCK();
  215. UDP6_EXIT();
  216. return err_code;
  217. }
  218. uint32_t udp6_socket_free(const udp6_socket_t * p_socket)
  219. {
  220. VERIFY_MODULE_IS_INITIALIZED();
  221. NULL_PARAM_CHECK(p_socket);
  222. VERIFY_SOCKET_ID(p_socket->socket_id);
  223. UDP6_ENTRY();
  224. UDP_MUTEX_LOCK();
  225. udp_socket_init(&m_socket[p_socket->socket_id]);
  226. UDP_MUTEX_UNLOCK();
  227. UDP6_EXIT();
  228. return NRF_SUCCESS;
  229. }
  230. uint32_t udp6_socket_recv(const udp6_socket_t * p_socket,
  231. const udp6_handler_t callback)
  232. {
  233. VERIFY_MODULE_IS_INITIALIZED();
  234. NULL_PARAM_CHECK(p_socket);
  235. NULL_PARAM_CHECK(callback);
  236. VERIFY_SOCKET_ID(p_socket->socket_id);
  237. VERIFY_PORT_NUMBER(m_socket[p_socket->socket_id].local_port);
  238. UDP6_ENTRY();
  239. UDP_MUTEX_LOCK();
  240. m_socket[p_socket->socket_id].rx_cb = callback;
  241. UDP_MUTEX_UNLOCK();
  242. UDP6_EXIT();
  243. return NRF_SUCCESS;
  244. }
  245. uint32_t udp6_socket_bind(const udp6_socket_t * p_socket,
  246. const ipv6_addr_t * p_src_addr,
  247. uint16_t src_port)
  248. {
  249. VERIFY_MODULE_IS_INITIALIZED();
  250. NULL_PARAM_CHECK(p_socket);
  251. NULL_PARAM_CHECK(p_src_addr);
  252. VERIFY_SOCKET_ID(p_socket->socket_id);
  253. VERIFY_PORT_NUMBER(src_port);
  254. UDP6_ENTRY();
  255. UDP_MUTEX_LOCK();
  256. uint32_t err_code = NRF_SUCCESS;
  257. // Change Host Byte Order to Network Byte Order.
  258. src_port = HTONS(src_port);
  259. //Check if port is already registered.
  260. for (uint32_t index = 0; index < UDP6_MAX_SOCKET_COUNT; index ++)
  261. {
  262. if (m_socket[index].local_port == src_port)
  263. {
  264. err_code = UDP_PORT_IN_USE;
  265. }
  266. }
  267. if (err_code == NRF_SUCCESS)
  268. {
  269. m_socket[p_socket->socket_id].local_port = src_port;
  270. m_socket[p_socket->socket_id].local_addr = (*p_src_addr);
  271. }
  272. UDP_MUTEX_UNLOCK();
  273. UDP6_EXIT();
  274. return err_code;
  275. }
  276. uint32_t udp6_socket_connect(const udp6_socket_t * p_socket,
  277. const ipv6_addr_t * p_dest_addr,
  278. uint16_t dest_port)
  279. {
  280. VERIFY_MODULE_IS_INITIALIZED();
  281. NULL_PARAM_CHECK(p_socket);
  282. NULL_PARAM_CHECK(p_dest_addr);
  283. VERIFY_SOCKET_ID(p_socket->socket_id);
  284. VERIFY_PORT_NUMBER(dest_port);
  285. VERIFY_PORT_NUMBER(m_socket[p_socket->socket_id].local_port);
  286. UDP6_ENTRY();
  287. UDP_MUTEX_LOCK();
  288. m_socket[p_socket->socket_id].remote_port = HTONS(dest_port);
  289. m_socket[p_socket->socket_id].remote_addr = (*p_dest_addr);
  290. UDP_MUTEX_UNLOCK();
  291. UDP6_EXIT();
  292. return NRF_SUCCESS;
  293. }
  294. uint32_t udp6_socket_send(const udp6_socket_t * p_socket,
  295. iot_pbuffer_t * p_packet)
  296. {
  297. VERIFY_MODULE_IS_INITIALIZED();
  298. NULL_PARAM_CHECK(p_socket);
  299. NULL_PARAM_CHECK(p_packet);
  300. NULL_PARAM_CHECK(p_packet->p_payload);
  301. VERIFY_NON_ZERO_LENGTH(p_packet->length);
  302. VERIFY_SOCKET_ID(p_socket->socket_id);
  303. VERIFY_PORT_NUMBER(m_socket[p_socket->socket_id].local_port);
  304. VERIFY_PORT_NUMBER(m_socket[p_socket->socket_id].remote_port);
  305. UDP6_ENTRY();
  306. UDP_MUTEX_LOCK();
  307. uint32_t err_code;
  308. const udp_socket_entry_t * p_skt = &m_socket[p_socket->socket_id];
  309. const uint32_t header_size = UDP_HEADER_SIZE + IPV6_IP_HEADER_SIZE;
  310. udp6_header_t * p_header = (udp6_header_t *)(p_packet->p_payload - UDP_HEADER_SIZE);
  311. ipv6_header_t * p_ip_header = (ipv6_header_t *)(p_packet->p_payload - header_size);
  312. iot_interface_t * p_interface = NULL;
  313. uint16_t checksum;
  314. p_header->srcport = p_skt->local_port;
  315. p_header->destport = p_skt->remote_port;
  316. p_header->checksum = 0;
  317. p_header->length = HTONS(p_packet->length + UDP_HEADER_SIZE);
  318. // Pack destination address.
  319. p_ip_header->destaddr = p_skt->remote_addr;
  320. // Pack source address.
  321. if ((0 == IPV6_ADDRESS_CMP(&p_skt->local_addr, IPV6_ADDR_ANY)))
  322. {
  323. err_code = ipv6_address_find_best_match(&p_interface,
  324. &p_ip_header->srcaddr,
  325. &p_ip_header->destaddr);
  326. }
  327. else
  328. {
  329. err_code = ipv6_address_find_best_match(&p_interface,
  330. NULL,
  331. &p_ip_header->destaddr);
  332. p_ip_header->srcaddr = p_skt->local_addr;
  333. }
  334. if (err_code == NRF_SUCCESS)
  335. {
  336. // Pack next header.
  337. p_ip_header->next_header = IPV6_NEXT_HEADER_UDP;
  338. //Pack HOP Limit.
  339. p_ip_header->hoplimit = IPV6_DEFAULT_HOP_LIMIT;
  340. //Traffic class and flow label.
  341. p_ip_header->version_traffic_class = 0x60;
  342. p_ip_header->traffic_class_flowlabel = 0x00;
  343. p_ip_header->flowlabel = 0x0000;
  344. // Length.
  345. p_ip_header->length = HTONS(p_packet->length + UDP_HEADER_SIZE);
  346. checksum = p_packet->length + UDP_HEADER_SIZE + IPV6_NEXT_HEADER_UDP;
  347. ipv6_checksum_calculate(p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
  348. ipv6_checksum_calculate(p_ip_header->destaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
  349. ipv6_checksum_calculate(p_packet->p_payload - UDP_HEADER_SIZE,
  350. p_packet->length + UDP_HEADER_SIZE,
  351. &checksum,
  352. true);
  353. p_header->checksum = HTONS((~checksum));
  354. p_packet->p_payload -= header_size;
  355. p_packet->length += header_size;
  356. err_code = ipv6_send(p_interface, p_packet);
  357. }
  358. else
  359. {
  360. err_code = UDP_INTERFACE_NOT_READY;
  361. }
  362. UDP_MUTEX_UNLOCK();
  363. UDP6_EXIT();
  364. return err_code;
  365. }
  366. uint32_t udp6_socket_sendto(const udp6_socket_t * p_socket,
  367. const ipv6_addr_t * p_dest_addr,
  368. uint16_t dest_port,
  369. iot_pbuffer_t * p_packet)
  370. {
  371. VERIFY_MODULE_IS_INITIALIZED();
  372. NULL_PARAM_CHECK(p_socket);
  373. NULL_PARAM_CHECK(p_dest_addr);
  374. NULL_PARAM_CHECK(p_packet);
  375. NULL_PARAM_CHECK(p_packet->p_payload);
  376. VERIFY_NON_ZERO_LENGTH(p_packet->length);
  377. VERIFY_SOCKET_ID(p_socket->socket_id);
  378. VERIFY_PORT_NUMBER(dest_port);
  379. UDP6_ENTRY();
  380. UDP_MUTEX_LOCK();
  381. uint32_t err_code;
  382. const udp_socket_entry_t * p_skt = &m_socket[p_socket->socket_id];
  383. const uint32_t header_size = UDP_HEADER_SIZE + IPV6_IP_HEADER_SIZE;
  384. udp6_header_t * p_header = (udp6_header_t *)(p_packet->p_payload - UDP_HEADER_SIZE);
  385. ipv6_header_t * p_ip_header = (ipv6_header_t *)(p_packet->p_payload - header_size);
  386. iot_interface_t * p_interface = NULL;
  387. uint16_t checksum;
  388. p_header->srcport = p_skt->local_port;
  389. p_header->destport = HTONS(dest_port);
  390. p_header->checksum = 0;
  391. checksum = p_packet->length + UDP_HEADER_SIZE + IPV6_NEXT_HEADER_UDP;
  392. p_header->length = HTONS(p_packet->length + UDP_HEADER_SIZE);
  393. //Pack destination address.
  394. p_ip_header->destaddr = *p_dest_addr;
  395. // Pack source address.
  396. if ((0 == IPV6_ADDRESS_CMP(&p_skt->local_addr, IPV6_ADDR_ANY)))
  397. {
  398. err_code = ipv6_address_find_best_match(&p_interface,
  399. &p_ip_header->srcaddr,
  400. &p_ip_header->destaddr);
  401. }
  402. else
  403. {
  404. err_code = ipv6_address_find_best_match(&p_interface,
  405. NULL,
  406. &p_ip_header->destaddr);
  407. p_ip_header->srcaddr = p_skt->local_addr;
  408. }
  409. if (err_code == NRF_SUCCESS)
  410. {
  411. //Pack next header.
  412. p_ip_header->next_header = IPV6_NEXT_HEADER_UDP;
  413. //Pack HOP Limit.
  414. p_ip_header->hoplimit = IPV6_DEFAULT_HOP_LIMIT;
  415. //Traffic class and flow label.
  416. p_ip_header->version_traffic_class = 0x60;
  417. p_ip_header->traffic_class_flowlabel = 0x00;
  418. p_ip_header->flowlabel = 0x0000;
  419. // Length.
  420. p_ip_header->length = HTONS(p_packet->length + UDP_HEADER_SIZE);
  421. ipv6_checksum_calculate(p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
  422. ipv6_checksum_calculate(p_ip_header->destaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
  423. ipv6_checksum_calculate(p_packet->p_payload - UDP_HEADER_SIZE,
  424. p_packet->length + UDP_HEADER_SIZE,
  425. &checksum,
  426. true);
  427. p_header->checksum = HTONS((~checksum));
  428. p_packet->p_payload -= header_size;
  429. p_packet->length += header_size;
  430. err_code = ipv6_send(p_interface, p_packet);
  431. }
  432. else
  433. {
  434. err_code = UDP_INTERFACE_NOT_READY;
  435. }
  436. UDP_MUTEX_UNLOCK();
  437. UDP6_EXIT();
  438. return err_code;
  439. }
  440. uint32_t udp6_socket_app_data_set(const udp6_socket_t * p_socket)
  441. {
  442. VERIFY_MODULE_IS_INITIALIZED();
  443. NULL_PARAM_CHECK(p_socket);
  444. VERIFY_SOCKET_ID(p_socket->socket_id);
  445. //Note: no null check is performed on the p_app_data as it is permissible
  446. //to pass on a NULL value if need be.
  447. UDP6_ENTRY();
  448. UDP_MUTEX_LOCK();
  449. m_socket[p_socket->socket_id].p_app_data = p_socket->p_app_data;
  450. UDP_MUTEX_UNLOCK();
  451. UDP6_EXIT();
  452. return NRF_SUCCESS;
  453. }
  454. uint32_t udp_input(const iot_interface_t * p_interface,
  455. const ipv6_header_t * p_ip_header,
  456. iot_pbuffer_t * p_packet)
  457. {
  458. NULL_PARAM_CHECK(p_interface);
  459. NULL_PARAM_CHECK(p_ip_header);
  460. NULL_PARAM_CHECK(p_packet);
  461. UNUSED_VARIABLE(p_interface);
  462. uint32_t err_code = (NRF_ERROR_NOT_FOUND | IOT_UDP6_ERR_BASE);
  463. if ((p_packet->length > UDP_HEADER_SIZE) && (p_ip_header->length > UDP_HEADER_SIZE))
  464. {
  465. UDP_MUTEX_LOCK();
  466. UDP6_ENTRY();
  467. uint32_t index;
  468. udp6_header_t * p_udp_header = (udp6_header_t *)(p_packet->p_payload);
  469. // Check to which UDP socket, port and address was bind.
  470. for (index = 0; index < UDP6_MAX_SOCKET_COUNT; index ++)
  471. {
  472. if (m_socket[index].local_port == p_udp_header->destport)
  473. {
  474. if ((0 == IPV6_ADDRESS_CMP(&m_socket[index].local_addr, IPV6_ADDR_ANY)) ||
  475. (0 == IPV6_ADDRESS_CMP(&m_socket[index].local_addr, &p_ip_header->destaddr)))
  476. {
  477. // Check if connection was established.
  478. if (m_socket[index].remote_port == 0 || m_socket[index].remote_port == p_udp_header->srcport)
  479. {
  480. if ((0 == IPV6_ADDRESS_CMP(&m_socket[index].remote_addr, IPV6_ADDR_ANY)) ||
  481. (0 == IPV6_ADDRESS_CMP(&m_socket[index].remote_addr, &p_ip_header->srcaddr)))
  482. {
  483. err_code = NRF_SUCCESS;
  484. break;
  485. }
  486. }
  487. }
  488. }
  489. }
  490. if (index < UDP6_MAX_SOCKET_COUNT)
  491. {
  492. uint16_t checksum = p_packet->length + IPV6_NEXT_HEADER_UDP;
  493. uint32_t process_result = NRF_SUCCESS;
  494. uint16_t udp_hdr_length = NTOHS(p_udp_header->length);
  495. if (udp_hdr_length > p_packet->length)
  496. {
  497. UDP6_ERR("Received truncated packet, "
  498. "payload length 0x%08lX, length in header 0x%08X.",
  499. p_packet->length, NTOHS(p_udp_header->length));
  500. process_result = UDP_TRUNCATED_PACKET;
  501. }
  502. else if (udp_hdr_length < p_packet->length)
  503. {
  504. UDP6_ERR("Received malformed packet, "
  505. "payload length 0x%08lX, length in header 0x%08X.",
  506. p_packet->length, NTOHS(p_udp_header->length));
  507. process_result = UDP_MALFORMED_PACKET;
  508. }
  509. else
  510. {
  511. ipv6_checksum_calculate(p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
  512. ipv6_checksum_calculate(p_ip_header->destaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
  513. ipv6_checksum_calculate(p_packet->p_payload, p_packet->length, &checksum, false);
  514. if (checksum != 0 && checksum != 0xFFFF)
  515. {
  516. UDP6_ERR("Bad checksum detected.");
  517. process_result = UDP_BAD_CHECKSUM;
  518. }
  519. }
  520. p_packet->p_payload = p_packet->p_payload + UDP_HEADER_SIZE;
  521. p_packet->length -= UDP_HEADER_SIZE;
  522. //Found port for which data is intended.
  523. const udp6_socket_t sock = {index, m_socket[index].p_app_data};
  524. //Give application a callback if callback is registered.
  525. if (m_socket[index].rx_cb != NULL)
  526. {
  527. UDP_MUTEX_UNLOCK();
  528. // Change byte ordering given to application.
  529. p_udp_header->destport = NTOHS(p_udp_header->destport);
  530. p_udp_header->srcport = NTOHS(p_udp_header->srcport);
  531. p_udp_header->length = NTOHS(p_udp_header->length);
  532. p_udp_header->checksum = NTOHS(p_udp_header->checksum);
  533. err_code = m_socket[index].rx_cb(&sock, p_ip_header, p_udp_header, process_result, p_packet);
  534. UDP_MUTEX_LOCK();
  535. }
  536. }
  537. else
  538. {
  539. UDP6_ERR("Packet received on unknown port, dropping!");
  540. }
  541. UDP_MUTEX_UNLOCK();
  542. UDP6_EXIT();
  543. }
  544. else
  545. {
  546. UDP6_ERR("Packet of length less than UDP header size received!");
  547. err_code = (IOT_UDP6_ERR_BASE | NRF_ERROR_INVALID_LENGTH);
  548. }
  549. return err_code;
  550. }