int32_t destiny_socket_sendto(int s, const void *buf, uint32_t len, int flags, sockaddr6_t *to, uint32_t tolen) { if (isUDPSocket(s) && (get_socket(s)->socket_values.foreign_address.sin6_port == 0)) { uint8_t send_buffer[BUFFER_SIZE]; ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t *)(&send_buffer)); udp_hdr_t *current_udp_packet = ((udp_hdr_t *)(&send_buffer[IPV6_HDR_LEN])); uint8_t *payload = &send_buffer[IPV6_HDR_LEN + UDP_HDR_LEN]; memcpy(&(temp_ipv6_header->destaddr), &to->sin6_addr, 16); ipv6_iface_get_best_src_addr(&(temp_ipv6_header->srcaddr), &(temp_ipv6_header->destaddr)); current_udp_packet->src_port = get_free_source_port(IPPROTO_UDP); current_udp_packet->dst_port = to->sin6_port; current_udp_packet->checksum = 0; memcpy(payload, buf, len); current_udp_packet->length = HTONS(UDP_HDR_LEN + len); temp_ipv6_header->length = UDP_HDR_LEN + len; current_udp_packet->checksum = ~udp_csum(temp_ipv6_header, current_udp_packet); ipv6_sendto(&to->sin6_addr, IPPROTO_UDP, (uint8_t *)(current_udp_packet), NTOHS(current_udp_packet->length)); return current_udp_packet->length; } else { return -1; } }
uint8_t rpl_init(transceiver_type_t trans, uint16_t rpl_address) { mutex_init(&rpl_send_mutex); mutex_init(&rpl_recv_mutex); if (rpl_address == 0) { return SIXLOWERROR_ADDRESS; } /* initialize routing table */ rpl_clear_routing_table(); init_trickle(); rpl_process_pid = thread_create(rpl_process_buf, RPL_PROCESS_STACKSIZE, PRIORITY_MAIN - 1, CREATE_STACKTEST, rpl_process, "rpl_process"); /* INSERT NEW OBJECTIVE FUNCTIONS HERE */ objective_functions[0] = rpl_get_of0(); /* objective_functions[1] = rpl_get_of_ETX() */ sixlowpan_lowpan_init(trans, rpl_address, 0); /* need link local prefix to query _our_ corresponding address */ ipv6_addr_t ll_address; ipv6_addr_set_link_local_prefix(&ll_address); ipv6_iface_get_best_src_addr(&my_address, &ll_address); ipv6_register_rpl_handler(rpl_process_pid); /* initialize ETX-calculation if needed */ if (RPL_DEFAULT_OCP == 1) { DEBUG("INIT ETX BEACONING\n"); etx_init_beaconing(&my_address); } return SIXLOWERROR_SUCCESS; }
/* TODO: tcp_socket unused? */ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_t next_header, void *tcp_socket) { uint8_t *p_ptr; ipv6_send_buf = get_rpl_send_ipv6_buf(); p_ptr = get_rpl_send_payload_buf(ipv6_ext_hdr_len); uint16_t packet_length = 0; ipv6_send_buf->version_trafficclass = IPV6_VER; ipv6_send_buf->trafficclass_flowlabel = 0; ipv6_send_buf->flowlabel = 0; ipv6_send_buf->nextheader = next_header; ipv6_send_buf->hoplimit = MULTIHOP_HOPLIMIT; ipv6_send_buf->length = p_len; memcpy(&(ipv6_send_buf->destaddr), destination, 16); ipv6_iface_get_best_src_addr(&(ipv6_send_buf->srcaddr), &(ipv6_send_buf->destaddr)); /* The packet was "assembled" in rpl.c. Therefore rpl_send_buf was used. * Therefore memcpy is not needed because the payload is at the * right memory location already. */ if (p_ptr != payload) { memcpy(p_ptr, payload, p_len); } packet_length = IPV6_HDR_LEN + p_len; if (ipv6_addr_is_multicast(&ipv6_send_buf->destaddr)) { sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(ipv6_send_buf->destaddr.uint16[4]), (uint8_t *)ipv6_send_buf, packet_length); } else { /* find appropriate next hop before sending */ ipv6_addr_t *next_hop = rpl_get_next_hop(&ipv6_send_buf->destaddr); if (next_hop == NULL) { if (i_am_root) { DEBUG("[Error] destination unknown\n"); return; } else { next_hop = rpl_get_my_preferred_parent(); if (next_hop == NULL) { DEBUG("[Error] no preferred parent, dropping package\n"); return; } } } sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(next_hop->uint16[4]), (uint8_t *)ipv6_send_buf, packet_length); } }
int destiny_socket_connect(int socket, sockaddr6_t *addr, uint32_t addrlen) { /* Variables */ ipv6_addr_t src_addr; socket_internal_t *current_int_tcp_socket; socket_t *current_tcp_socket; msg_t msg_from_server; uint8_t send_buffer[BUFFER_SIZE]; ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t *)(&send_buffer)); tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t *)(&send_buffer[IPV6_HDR_LEN])); /* Check if socket exists */ current_int_tcp_socket = get_socket(socket); if (current_int_tcp_socket == NULL) { return -1; } current_tcp_socket = ¤t_int_tcp_socket->socket_values; current_int_tcp_socket->recv_pid = thread_getpid(); /* Local address information */ ipv6_iface_get_best_src_addr(&src_addr, &addr->sin6_addr); set_socket_address(¤t_tcp_socket->local_address, PF_INET6, HTONS(get_free_source_port(IPPROTO_TCP)), 0, &src_addr); /* Foreign address information */ set_socket_address(¤t_tcp_socket->foreign_address, addr->sin6_family, addr->sin6_port, addr->sin6_flowinfo, &addr->sin6_addr); /* Fill lcoal TCP socket information */ srand(addr->sin6_port); current_tcp_socket->tcp_control.rcv_irs = 0; mutex_lock(&global_sequence_clunter_mutex); current_tcp_socket->tcp_control.send_iss = global_sequence_counter; mutex_unlock(&global_sequence_clunter_mutex); current_tcp_socket->tcp_control.state = SYN_SENT; #ifdef TCP_HC /* Choosing random number Context ID */ mutex_lock(&global_context_counter_mutex); current_tcp_socket->tcp_control.tcp_context.context_id = global_context_counter; mutex_unlock(&global_context_counter_mutex); current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER; /* Remember TCP Context for possible TCP_RETRY */ tcp_hc_context_t saved_tcp_context; memcpy(&saved_tcp_context, ¤t_tcp_socket->tcp_control.tcp_context, sizeof(tcp_hc_context_t)); #endif set_tcp_cb(¤t_tcp_socket->tcp_control, 0, DESTINY_SOCKET_STATIC_WINDOW, current_tcp_socket->tcp_control.send_iss, current_tcp_socket->tcp_control.send_iss, 0); /* Remember current time */ timex_t now; vtimer_now(&now); current_tcp_socket->tcp_control.last_packet_time = now; current_tcp_socket->tcp_control.no_of_retries = 0; msg_from_server.type = TCP_RETRY; while (msg_from_server.type == TCP_RETRY) { /* Send packet */ send_tcp(current_int_tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_SYN, 0); /* wait for SYN ACK or RETRY */ msg_receive(&msg_from_server); if (msg_from_server.type == TCP_TIMEOUT) { #ifdef TCP_HC /* We did not send anything successful so restore last context */ memcpy(¤t_tcp_socket->tcp_control.tcp_context, &saved_tcp_context, sizeof(tcp_hc_context_t)); #endif return -1; } #ifdef TCP_HC else if (msg_from_server.type == TCP_RETRY) { /* We retry sending a packet so set everything to last values again */ memcpy(¤t_tcp_socket->tcp_control.tcp_context, &saved_tcp_context, sizeof(tcp_hc_context_t)); } #endif } /* Read packet content */ tcp_hdr_t *tcp_header = ((tcp_hdr_t *)(msg_from_server.content.ptr)); /* Check for consistency */ if (tcp_header->ack_nr != current_tcp_socket->tcp_control.send_nxt + 1) { printf("TCP packets not consistent!\n"); } /* Got SYN ACK from Server */ /* Refresh foreign TCP socket information */ if ((tcp_header->dataOffset_reserved * 4 > TCP_HDR_LEN) && (*(((uint8_t *)tcp_header) + TCP_HDR_LEN) == TCP_MSS_OPTION)) { current_tcp_socket->tcp_control.mss = *((uint16_t *)(((uint8_t *)tcp_header) + TCP_HDR_LEN + 2)); } else { current_tcp_socket->tcp_control.mss = DESTINY_SOCKET_STATIC_MSS; } current_tcp_socket->tcp_control.rcv_irs = tcp_header->seq_nr; set_tcp_cb(¤t_tcp_socket->tcp_control, tcp_header->seq_nr + 1, current_tcp_socket->tcp_control.rcv_wnd, current_tcp_socket->tcp_control.send_una, current_tcp_socket->tcp_control.send_una, tcp_header->window); current_tcp_socket->tcp_control.send_una++; current_tcp_socket->tcp_control.send_nxt++; msg_from_server.type = UNDEFINED; /* Remember current time */ vtimer_now(&now); current_tcp_socket->tcp_control.last_packet_time = now; current_tcp_socket->tcp_control.no_of_retries = 0; #ifdef TCP_HC current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER; /* Remember TCP Context for possible TCP_RETRY */ memcpy(&saved_tcp_context, ¤t_tcp_socket->tcp_control.tcp_context, sizeof(tcp_hc_context_t)); #endif while (msg_from_server.type != TCP_RETRY) { /* Send packet */ send_tcp(current_int_tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_ACK, 0); msg_receive(&msg_from_server); #ifdef TCP_HC if (msg_from_server.type == TCP_SYN_ACK) { /* TCP_SYN_ACK from server arrived again, copy old context and * send TCP_ACK again */ memcpy(¤t_tcp_socket->tcp_control.tcp_context, &saved_tcp_context, sizeof(tcp_hc_context_t)); } else if (msg_from_server.type == TCP_RETRY) { /* We waited for RTT, no TCP_SYN_ACK received, so we assume the * TCP_ACK packet arrived safely */ } #endif } current_tcp_socket->tcp_control.state = ESTABLISHED; current_int_tcp_socket->recv_pid = 255; destiny_socket_print_sockets(); return 0; }