uint32_t ipv6_send(const iot_interface_t * p_interface, iot_pbuffer_t * p_packet) { VERIFY_MODULE_IS_INITIALIZED(); NULL_PARAM_CHECK(p_packet); NULL_PARAM_CHECK(p_interface); uint32_t err_code; IPV6_MUTEX_LOCK(); IPV6_ENTRY(); err_code = ble_6lowpan_interface_send(p_interface, p_packet->p_payload, p_packet->length); if (err_code != NRF_SUCCESS) { IPV6_ERR("Cannot send packet!"); } // Free pbuffer, without freeing memory. UNUSED_VARIABLE(iot_pbuffer_free(p_packet, false)); IPV6_EXIT(); IPV6_MUTEX_UNLOCK(); return err_code; }
int connect(int sock, const void * p_addr, socklen_t addrlen) { VERIFY_MODULE_IS_INITIALIZED(); VERIFY_SOCKET_ID(sock); NULL_PARAM_CHECK(p_addr); SOCKET_MUTEX_LOCK(); socket_entry_t * p_socket_entry = &m_socket_table[sock]; SOCKET_MUTEX_UNLOCK(); int ret = -1; if (p_socket_entry->state == STATE_OPEN) { uint32_t err_code = p_socket_entry->handler->connect_handler(&p_socket_entry->handle, p_addr, addrlen); if (err_code == NRF_SUCCESS) { p_socket_entry->state = STATE_CONNECTED; ret = 0; } socket_set_errno(err_code); } else if (p_socket_entry->state == STATE_CONNECTED) { set_errno(EISCONN); } else if (p_socket_entry->state == STATE_CLOSED) { set_errno(EBADF); } return ret; }
uint32_t iot_context_manager_get_by_cid(const iot_interface_t * p_interface, uint8_t context_id, iot_context_t ** pp_context) { VERIFY_MODULE_IS_INITIALIZED(); NULL_PARAM_CHECK(p_interface); NULL_PARAM_CHECK(pp_context); VERIFY_CID_VALUE(context_id); uint32_t err_code; CM_ENTRY(); CM_MUTEX_LOCK(); const uint32_t table_id = context_table_find(p_interface); if (table_id != IOT_CONTEXT_MANAGER_MAX_TABLES) { err_code = context_find_by_cid(table_id, context_id, pp_context); } else { // No free context table found. CM_TRC("No context table found."); err_code = (NRF_ERROR_NOT_FOUND | IOT_CONTEXT_MANAGER_ERR_BASE); } CM_MUTEX_UNLOCK(); CM_EXIT(); return err_code; }
ssize_t recv(int sock, void * p_buf, size_t buf_size, int flags) { VERIFY_MODULE_IS_INITIALIZED(); VERIFY_SOCKET_ID(sock); NULL_PARAM_CHECK(p_buf); SOCKET_MUTEX_LOCK(); socket_entry_t * p_socket_entry = &m_socket_table[sock]; SOCKET_MUTEX_UNLOCK(); ssize_t ret = -1; if (p_socket_entry->state == STATE_CONNECTED) { uint32_t recv_size = 0; uint32_t err_code = socket_recv(&p_socket_entry->handle, p_buf, buf_size, &recv_size, flags); if (err_code == NRF_SUCCESS) { ret = (ssize_t) recv_size; } socket_set_errno(err_code); } else { set_errno(ENOTCONN); } return ret; }
uint32_t iot_context_manager_get_by_addr(const iot_interface_t * p_interface, const ipv6_addr_t * p_addr, iot_context_t ** pp_context) { VERIFY_MODULE_IS_INITIALIZED(); NULL_PARAM_CHECK(p_interface); NULL_PARAM_CHECK(p_addr); NULL_PARAM_CHECK(pp_context); uint32_t err_code; CM_TRC("[CONTEXT_MANAGER]: >> iot_context_manager_get_by_addr\r\n"); CM_MUTEX_LOCK(); const uint32_t table_id = context_table_find(p_interface); if (table_id != IOT_CONTEXT_MANAGER_MAX_TABLES) { err_code = context_find_by_prefix(table_id, p_addr, pp_context); } else { // No free context table found. CM_TRC("[CONTEXT_MANAGER]: No context table found.\r\n"); err_code = (NRF_ERROR_NOT_FOUND | IOT_CONTEXT_MANAGER_ERR_BASE); } CM_MUTEX_UNLOCK(); CM_TRC("[CONTEXT_MANAGER]: << iot_context_manager_get_by_addr\r\n"); return err_code; }
uint32_t iot_context_manager_table_alloc(const iot_interface_t * p_interface) { VERIFY_MODULE_IS_INITIALIZED(); NULL_PARAM_CHECK(p_interface); uint32_t err_code = NRF_SUCCESS; CM_ENTRY(); CM_MUTEX_LOCK(); const uint32_t table_id = context_table_find(NULL); if (table_id != IOT_CONTEXT_MANAGER_MAX_TABLES) { // Found a free context table and assign to it. CM_TRC("Assigned new context table."); m_context_table[table_id].p_interface = (iot_interface_t *)p_interface; } else { // No free context table found. CM_ERR("No context table found."); err_code = (NRF_ERROR_NO_MEM | IOT_CONTEXT_MANAGER_ERR_BASE); } CM_MUTEX_UNLOCK(); CM_EXIT(); return err_code; }
uint32_t iot_context_manager_table_free(const iot_interface_t * p_interface) { VERIFY_MODULE_IS_INITIALIZED(); NULL_PARAM_CHECK(p_interface); uint32_t err_code = NRF_SUCCESS; CM_ENTRY(); SDK_MUTEX_INIT(m_iot_context_manager_mutex); CM_MUTEX_LOCK(); const uint32_t table_id = context_table_find(p_interface); if (table_id != IOT_CONTEXT_MANAGER_MAX_TABLES) { // Clear context table. CM_TRC("Found context table assigned to interface."); context_table_init(table_id); } else { // No free context table found. CM_ERR("No context table found."); err_code = (NRF_ERROR_NOT_FOUND | IOT_CONTEXT_MANAGER_ERR_BASE); } CM_MUTEX_UNLOCK(); CM_EXIT(); return err_code; }
uint32_t ipv6_address_find_best_match(iot_interface_t ** pp_interface, ipv6_addr_t * p_addr_r, const ipv6_addr_t * p_addr_f) { VERIFY_MODULE_IS_INITIALIZED(); NULL_PARAM_CHECK(p_addr_f); NULL_PARAM_CHECK(pp_interface); uint32_t index; uint32_t err_code; uint32_t addr_index; uint32_t match_temp = 0; uint32_t match_best = 0; ipv6_addr_t * p_best_addr = NULL; IPV6_MUTEX_LOCK(); err_code = interface_find(pp_interface, p_addr_f); if (err_code == NRF_SUCCESS && p_addr_r) { uint32_t interface_id = (uint32_t)(*pp_interface)->p_upper_stack; for (index = 0; index < IPV6_MAX_ADDRESS_PER_INTERFACE; index++) { addr_index = m_interfaces[interface_id].addr_range[index]; if (addr_index != IPV6_INVALID_ADDR_INDEX) { if (m_address_table[addr_index].state == IPV6_ADDR_STATE_PREFERRED) { match_temp = addr_bit_equal(p_addr_f, &m_address_table[addr_index].addr); if (match_temp >= match_best) { match_best = match_temp; p_best_addr = &m_address_table[addr_index].addr; } } } } // No address found. if (p_best_addr == NULL) { // Set undefined :: address. IPV6_ADDRESS_INITIALIZE(p_addr_r); } else { memcpy(p_addr_r->u8, p_best_addr->u8, IPV6_ADDR_SIZE); } } IPV6_MUTEX_UNLOCK(); return err_code; }
int listen(int sock, int backlog) { VERIFY_MODULE_IS_INITIALIZED(); VERIFY_SOCKET_ID(sock); (void) sock; (void) backlog; return -1; }
int accept(int sock, void * p_cliaddr, socklen_t * p_addrlen) { VERIFY_MODULE_IS_INITIALIZED(); VERIFY_SOCKET_ID(sock); NULL_PARAM_CHECK(p_cliaddr); (void) sock; (void) p_cliaddr; (void) p_addrlen; return -1; }
int bind(int sock, const void * p_myaddr, socklen_t addrlen) { VERIFY_MODULE_IS_INITIALIZED(); VERIFY_SOCKET_ID(sock); NULL_PARAM_CHECK(p_myaddr); (void) sock; (void) p_myaddr; (void) addrlen; return -1; }
int getsockopt(int sock, socket_opt_lvl_t level, int optname, void *optval, socklen_t *optlen) { VERIFY_MODULE_IS_INITIALIZED(); VERIFY_SOCKET_ID(sock); (void) sock; (void) level; (void) optname; (void) optval; (void) optlen; return -1; }
int socket(socket_family_t family, socket_type_t type, socket_protocol_t protocol) { if (m_initialization_state == false) { (void) socket_init(); } VERIFY_MODULE_IS_INITIALIZED(); int ret_sock = -1; int sock = socket_allocate(); SOCKET_TRACE("Got value %d from allocate\r\n", (int)sock); if (sock >= 0) { socket_entry_t *p_socket_entry = &m_socket_table[sock]; p_socket_entry->handle.params.family = family; p_socket_entry->handle.params.protocol = protocol; p_socket_entry->handle.params.type = type; p_socket_entry->handler = NULL; if (family == AF_INET6) { #if SOCKET_IPV6_ENABLE == 1 || SOCKET_LWIP_ENABLE == 1 p_socket_entry->handler = &transport_handler; #else set_errno(EAFNOSUPPORT); #endif // } else if (family == AF_BLE) { // TODO: Handle BLE } else { set_errno(EAFNOSUPPORT); } if (p_socket_entry->handler != NULL) { uint32_t err_code = p_socket_entry->handler->create_handler(&p_socket_entry->handle); socket_set_errno(err_code); ret_sock = (err_code == NRF_SUCCESS) ? sock : ret_sock; } if (ret_sock < 0) { socket_free(sock); } } SOCKET_TRACE("Returning socket value %d\r\n", (int)ret_sock); return ret_sock; }
int close(int sock) { VERIFY_MODULE_IS_INITIALIZED(); VERIFY_SOCKET_ID(sock); SOCKET_MUTEX_LOCK(); socket_entry_t * p_socket_entry = &m_socket_table[sock]; SOCKET_MUTEX_UNLOCK(); uint32_t err_code = p_socket_entry->handler->close_handler(&p_socket_entry->handle); int ret = (err_code == NRF_SUCCESS) ? 0 : -1; SOCKET_TRACE("Close socket %d: ret: %d\r\n", (int)sock, ret); socket_free(sock); return ret; }
uint32_t ipv6_address_remove(const iot_interface_t * p_interface, const ipv6_addr_t * p_addr) { VERIFY_MODULE_IS_INITIALIZED(); NULL_PARAM_CHECK(p_addr); NULL_PARAM_CHECK(p_interface); uint32_t index; uint32_t err_code; uint32_t addr_index; IPV6_MUTEX_LOCK(); IPV6_ENTRY(); uint32_t interface_id = (uint32_t)p_interface->p_upper_stack; err_code = (IOT_IPV6_ERR_BASE | NRF_ERROR_NOT_FOUND); for (index = 0; index < IPV6_MAX_ADDRESS_PER_INTERFACE; index++) { addr_index = m_interfaces[interface_id].addr_range[index]; if (addr_index != IPV6_INVALID_ADDR_INDEX) { if (0 == IPV6_ADDRESS_CMP(&m_address_table[addr_index].addr, p_addr)) { m_interfaces[interface_id].addr_range[index] = IPV6_INVALID_ADDR_INDEX; // Remove address if no reference to interface found. addr_free(index, true); err_code = NRF_SUCCESS; break; } } } IPV6_EXIT(); IPV6_MUTEX_UNLOCK(); return err_code; }
int fcntl(int fd, int cmd, int flags) { VERIFY_MODULE_IS_INITIALIZED(); VERIFY_SOCKET_ID(fd); if (cmd != F_SETFL) { set_errno(EINVAL); return -1; } SOCKET_MUTEX_LOCK(); socket_entry_t * p_socket_entry = &m_socket_table[fd]; SOCKET_MUTEX_UNLOCK(); p_socket_entry->handle.flags = flags; return 0; }
uint32_t icmp6_receive_register(icmp6_receive_callback_t cb) { VERIFY_MODULE_IS_INITIALIZED(); NULL_PARAM_CHECK(cb); UNUSED_VARIABLE(m_event_handler); ICMP6_MUTEX_LOCK(); ICMP6_TRC("[ICMP6]: >> icmp6_receive_register\r\n"); // Store application event handler. m_event_handler = cb; ICMP6_TRC("[ICMP6]: << icmp6_receive_register\r\n"); ICMP6_MUTEX_UNLOCK(); return NRF_SUCCESS; }
uint32_t ipv6_address_set(const iot_interface_t * p_interface, const ipv6_addr_conf_t * p_addr) { VERIFY_MODULE_IS_INITIALIZED(); NULL_PARAM_CHECK(p_addr); NULL_PARAM_CHECK(p_interface); uint32_t err_code; IPV6_MUTEX_LOCK(); IPV6_ENTRY(); err_code = addr_set(p_interface, p_addr); IPV6_EXIT(); IPV6_MUTEX_UNLOCK(); return err_code; }
uint32_t iot_context_manager_remove(const iot_interface_t * p_interface, iot_context_t * p_context) { VERIFY_MODULE_IS_INITIALIZED(); NULL_PARAM_CHECK(p_interface); NULL_PARAM_CHECK(p_context); uint32_t err_code = NRF_SUCCESS; CM_ENTRY(); CM_MUTEX_LOCK(); const uint32_t table_id = context_table_find(p_interface); if (table_id != IOT_CONTEXT_MANAGER_MAX_TABLES) { if (p_context->context_id != IPV6_CONTEXT_IDENTIFIER_NONE) { m_context_table[table_id].context_count--; } // Reinit context entry. context_init(p_context); } else { // No free context table found. CM_ERR("No context table found."); err_code = (NRF_ERROR_NOT_FOUND | IOT_CONTEXT_MANAGER_ERR_BASE); } CM_MUTEX_UNLOCK(); CM_EXIT(); return err_code; }
uint32_t ipv6_address_check(const iot_interface_t * p_interface, const ipv6_addr_t * p_addr) { VERIFY_MODULE_IS_INITIALIZED(); NULL_PARAM_CHECK(p_addr); NULL_PARAM_CHECK(p_interface); uint32_t err_code; IPV6_MUTEX_LOCK(); IPV6_ENTRY(); uint32_t interface_id = (uint32_t)p_interface->p_upper_stack; err_code = addr_check(interface_id, p_addr, false); IPV6_EXIT(); IPV6_MUTEX_UNLOCK(); return err_code; }
uint32_t iot_context_manager_update(const iot_interface_t * p_interface, iot_context_t * p_context) { VERIFY_MODULE_IS_INITIALIZED(); NULL_PARAM_CHECK(p_context); VERIFY_CID_VALUE(p_context->context_id); VERIFY_PREFIX_LEN_VALUE(p_context->prefix_len); uint32_t retval = NRF_SUCCESS; uint32_t err_code = NRF_SUCCESS; iot_context_t * p_internal_context; CM_ENTRY(); CM_MUTEX_LOCK(); const uint32_t table_id = context_table_find(p_interface); if (table_id != IOT_CONTEXT_MANAGER_MAX_TABLES) { // Try to find context in context table. retval = context_find_by_cid(table_id, p_context->context_id, &p_internal_context); if (retval != NRF_SUCCESS) { err_code = context_find_free(table_id, &p_internal_context); // Increase context count. if (err_code == NRF_SUCCESS) { m_context_table[table_id].context_count++; } } if (err_code == NRF_SUCCESS) { // Update context table, with parameters from application. p_internal_context->context_id = p_context->context_id; p_internal_context->prefix_len = p_context->prefix_len; p_internal_context->compression_flag = p_context->compression_flag; memset(p_internal_context->prefix.u8, 0, IPV6_ADDR_SIZE); IPV6_ADDRESS_PREFIX_SET(p_internal_context->prefix.u8, p_context->prefix.u8, p_context->prefix_len); } else { CM_ERR("No place in context table."); } } else { // No free context table found. CM_ERR("No context table found."); err_code = (NRF_ERROR_NOT_FOUND | IOT_CONTEXT_MANAGER_ERR_BASE); } CM_MUTEX_UNLOCK(); CM_EXIT(); return err_code; }
uint32_t icmp6_ns_send(const iot_interface_t * p_interface, const ipv6_addr_t * p_src_addr, const ipv6_addr_t * p_dest_addr, const icmp6_ns_param_t * p_param) { VERIFY_MODULE_IS_INITIALIZED(); NULL_PARAM_CHECK(p_interface); NULL_PARAM_CHECK(p_src_addr); NULL_PARAM_CHECK(p_dest_addr); NULL_PARAM_CHECK(p_param); uint32_t err_code = NRF_SUCCESS; uint16_t aro_size = 0; uint16_t checksum; iot_pbuffer_t * p_pbuffer; iot_pbuffer_alloc_param_t pbuff_param; // IPv6 Headers. ipv6_header_t * p_ip_header; icmp6_header_t * p_icmp_header; icmp6_ns_header_t * p_ns_header; nd_option_sllao_t * p_sllao_opt; nd_option_aro_t * p_aro_opt; ICMP6_MUTEX_LOCK(); ICMP6_TRC("[ICMP6]: >> icmp6_ndisc_ns_send\r\n"); if(p_param->add_aro) { aro_size = ND_OPT_ARO_SIZE; } // Requesting buffer for NS message pbuff_param.flags = PBUFFER_FLAG_DEFAULT; pbuff_param.type = ICMP6_PACKET_TYPE; pbuff_param.length = ND_NS_HEADER_SIZE + ND_OPT_SLLAO_SIZE + aro_size; err_code = iot_pbuffer_allocate(&pbuff_param, &p_pbuffer); if(err_code == NRF_SUCCESS) { p_ip_header = (ipv6_header_t *)(p_pbuffer->p_payload - ICMP6_HEADER_SIZE - IPV6_IP_HEADER_SIZE); p_icmp_header = (icmp6_header_t *)(p_pbuffer->p_payload - ICMP6_HEADER_SIZE); p_ns_header = (icmp6_ns_header_t *)(p_pbuffer->p_payload); p_sllao_opt = (nd_option_sllao_t *)(p_pbuffer->p_payload + ND_NS_HEADER_SIZE); p_aro_opt = (nd_option_aro_t *)(p_pbuffer->p_payload + ND_NS_HEADER_SIZE + ND_OPT_SLLAO_SIZE); // Change ICMP header. p_icmp_header->type = ICMP6_TYPE_NEIGHBOR_SOLICITATION; p_icmp_header->code = 0; p_icmp_header->checksum = 0; // IPv6 Header initialization. icmp_ip_header(p_ip_header, ND_HOP_LIMIT); p_ip_header->srcaddr = *p_src_addr; p_ip_header->destaddr = *p_dest_addr; p_ip_header->length = HTONS(p_pbuffer->length + ICMP6_HEADER_SIZE); // Set Neighbour Solicitation parameter. p_ns_header->reserved = 0; p_ns_header->target_addr = p_param->target_addr; // Add SLLAO option. add_sllao_opt(p_interface, p_sllao_opt); if(p_param->add_aro) { add_aro_opt(p_interface, p_aro_opt, p_param->aro_lifetime); } // Calculate checksum. checksum = p_pbuffer->length + ICMP6_HEADER_SIZE + IPV6_NEXT_HEADER_ICMP6; ipv6_checksum_calculate(p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE, &checksum, false); ipv6_checksum_calculate(p_ip_header->destaddr.u8, IPV6_ADDR_SIZE, &checksum, false); ipv6_checksum_calculate(p_pbuffer->p_payload - ICMP6_HEADER_SIZE, p_pbuffer->length + ICMP6_HEADER_SIZE, &checksum, false); p_icmp_header->checksum = HTONS((~checksum)); p_pbuffer->p_payload -= ICMP6_OFFSET; p_pbuffer->length += ICMP6_OFFSET; // Send IPv6 packet. err_code = ipv6_send(p_interface, p_pbuffer); } else { ICMP6_ERR("[ICMP6]: Failed to allocate packet buffer!\r\n"); } ICMP6_TRC("[ICMP6]: << icmp6_ndisc_ns_send\r\n"); ICMP6_MUTEX_UNLOCK(); return err_code; }
uint32_t icmp6_input(iot_interface_t * p_interface, ipv6_header_t * p_ip_header, iot_pbuffer_t * p_packet) { VERIFY_MODULE_IS_INITIALIZED(); NULL_PARAM_CHECK(p_interface); NULL_PARAM_CHECK(p_ip_header); NULL_PARAM_CHECK(p_packet); uint16_t checksum; uint32_t process_result = NRF_SUCCESS; bool is_ndisc = false; icmp6_header_t * p_icmp_header = (icmp6_header_t *)p_packet->p_payload; icmp6_echo_header_t * p_echo_header = NULL; uint32_t err_code = NRF_SUCCESS; SDK_MUTEX_LOCK(); ICMP6_TRC("[ICMP6]: >> icmp6_input\r\n"); if(p_packet->length < ICMP6_HEADER_SIZE || p_ip_header->length < ICMP6_HEADER_SIZE) { ICMP6_ERR("[ICMP6]: Received malformed packet, which has 0x%08lX bytes.\r\n", p_packet->length); process_result = ICMP6_MALFORMED_PACKET; } else { // Check checksum of packet. checksum = p_packet->length + IPV6_NEXT_HEADER_ICMP6; ipv6_checksum_calculate(p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE, &checksum, false); ipv6_checksum_calculate(p_ip_header->destaddr.u8, IPV6_ADDR_SIZE, &checksum, false); ipv6_checksum_calculate(p_packet->p_payload, p_packet->length, &checksum, false); checksum = (uint16_t)~checksum; // Change pbuffer type. p_packet->type = ICMP6_PACKET_TYPE; p_packet->p_payload = p_packet->p_payload + ICMP6_HEADER_SIZE; p_packet->length -= ICMP6_HEADER_SIZE; if (checksum != 0) { ICMP6_ERR("[ICMP6]: Bad checksum detected. Got 0x%08x but expected 0x%08x, 0x%08lX\r\n", NTOHS(p_icmp_header->checksum), checksum, p_packet->length); process_result = ICMP6_BAD_CHECKSUM; } else { switch(p_icmp_header->type) { case ICMP6_TYPE_DESTINATION_UNREACHABLE: case ICMP6_TYPE_PACKET_TOO_LONG: case ICMP6_TYPE_TIME_EXCEED: case ICMP6_TYPE_PARAMETER_PROBLEM: ICMP6_TRC("[ICMP6]: Got ICMPv6 error message with type = 0x%08x\r\n", p_icmp_header->type); break; case ICMP6_TYPE_ECHO_REQUEST: case ICMP6_TYPE_ECHO_REPLY: { p_echo_header = (icmp6_echo_header_t *)p_packet->p_payload; ICMP6_TRC("[ICMP6]: Got ICMPv6 Echo message with type = %x.\r\n", p_icmp_header->type); ICMP6_TRC("[ICMP6]: From:"); ICMP6_DUMP(p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE); ICMP6_TRC("[ICMP6]: Identifier: 0x%04x, Sequence Number: 0x%04x\r\n", NTOHS(p_echo_header->identifier), NTOHS(p_echo_header->sequence_number)); break; } case ICMP6_TYPE_ROUTER_SOLICITATION: case ICMP6_TYPE_ROUTER_ADVERTISEMENT: case ICMP6_TYPE_NEIGHBOR_SOLICITATION: case ICMP6_TYPE_NEIGHBOR_ADVERTISEMENT: process_result = ndisc_input(p_interface, p_ip_header, p_icmp_header, p_packet); is_ndisc = true; break; default: process_result = ICMP6_UNHANDLED_PACKET_TYPE; break; } } } #if (ICMP6_ENABLE_ALL_MESSAGES_TO_APPLICATION == 1) err_code = app_notify_icmp_data(p_interface, p_packet, process_result); #elif (ICMP6_ENABLE_ND6_MESSAGES_TO_APPLICATION == 1) if(is_ndisc) { err_code = app_notify_icmp_data(p_interface, p_packet, process_result); } #endif #if (ICMP6_ENABLE_HANDLE_ECHO_REQUEST_TO_APPLICATION == 0) if(p_icmp_header->type == ICMP6_TYPE_ECHO_REQUEST) { echo_reply_send(p_interface, p_ip_header, p_icmp_header, p_packet); } #endif ICMP6_TRC("[ICMP6]: << icmp6_input\r\n"); UNUSED_VARIABLE(is_ndisc); UNUSED_VARIABLE(p_echo_header); UNUSED_VARIABLE(process_result); SDK_MUTEX_UNLOCK(); return err_code; }
uint32_t icmp6_echo_request(const iot_interface_t * p_interface, const ipv6_addr_t * p_src_addr, const ipv6_addr_t * p_dest_addr, iot_pbuffer_t * p_request) { VERIFY_MODULE_IS_INITIALIZED(); NULL_PARAM_CHECK(p_interface); NULL_PARAM_CHECK(p_src_addr); NULL_PARAM_CHECK(p_dest_addr); NULL_PARAM_CHECK(p_request); PACKET_TYPE_CHECK(p_request); uint32_t err_code = NRF_SUCCESS; uint16_t checksum; ipv6_header_t * p_ip_header; icmp6_header_t * p_icmp_header; icmp6_echo_header_t * p_echo_header; ICMP6_MUTEX_LOCK(); ICMP6_TRC("[ICMP6]: >> icmp6_echo_request\r\n"); // Headers of IPv6 packet. p_ip_header = (ipv6_header_t *)(p_request->p_payload - ICMP6_HEADER_SIZE - IPV6_IP_HEADER_SIZE); p_icmp_header = (icmp6_header_t *)(p_request->p_payload - ICMP6_HEADER_SIZE); p_echo_header = (icmp6_echo_header_t *)(p_request->p_payload); // Change ICMP header. p_icmp_header->type = ICMP6_TYPE_ECHO_REQUEST; p_icmp_header->code = 0; p_icmp_header->checksum = 0; // IPv6 Header initialization. icmp_ip_header(p_ip_header, IPV6_DEFAULT_HOP_LIMIT); p_ip_header->srcaddr = *p_src_addr; p_ip_header->destaddr = *p_dest_addr; p_ip_header->length = HTONS(p_request->length + ICMP6_HEADER_SIZE); // Set echo reply parameters. p_echo_header->identifier = 0; p_echo_header->sequence_number = HTONS(m_sequence_number); // Calculate checksum. checksum = p_request->length + ICMP6_HEADER_SIZE + IPV6_NEXT_HEADER_ICMP6; ipv6_checksum_calculate(p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE, &checksum, false); ipv6_checksum_calculate(p_ip_header->destaddr.u8, IPV6_ADDR_SIZE, &checksum, false); ipv6_checksum_calculate(p_request->p_payload - ICMP6_HEADER_SIZE, p_request->length + ICMP6_HEADER_SIZE, &checksum, false); p_icmp_header->checksum = HTONS((~checksum)); m_sequence_number++; p_request->p_payload -= ICMP6_OFFSET; p_request->length += ICMP6_OFFSET; // Send IPv6 packet. err_code = ipv6_send(p_interface, p_request); ICMP6_TRC("[ICMP6]: << icmp6_echo_request\r\n"); ICMP6_MUTEX_UNLOCK(); return err_code; }