/*---------------------------------------------------------------------------*/ void tcpip_init(void) { #if UIP_TCP { static unsigned char i; for(i = 0; i < UIP_LISTENPORTS; ++i) { s.listenports[i].port = 0; } } #endif evproc_regCallback(EVENT_TYPE_TCP_POLL,eventhandler); evproc_regCallback(EVENT_TYPE_UDP_POLL,eventhandler); evproc_regCallback(EVENT_TYPE_PCK_INPUT,eventhandler); #if UIP_CONF_ICMP6 evproc_regCallback(EVENT_TYPE_ICMP6,eventhandler); // it is neede to register callback #endif /* UIP_CONF_ICMP6 */ etimer_set(&periodic, bsp_get(E_BSP_GET_TRES) / 2, eventhandler); uip_init(); #ifdef UIP_FALLBACK_INTERFACE UIP_FALLBACK_INTERFACE.init(); #endif /* initialize RPL if configured for using RPL */ #if UIP_CONF_IPV6_RPL rpl_init(); #endif /* UIP_CONF_IPV6_RPL */ }
/*----------------------------------------------------------------------------*/ int8_t demo_udp_socket_init(void) { /* The choice of server address determines its 6LoPAN header compression. * (Our address will be compressed Mode 3 since it is derived from our link-local address) * Obviously the choice made here must also be selected in udp-server.c. * * For correct Wireshark decoding using a sniffer, add the /64 prefix to the 6LowPAN protocol preferences, * e.g. set Context 0 to aaaa::. At present Wireshark copies Context/128 and then overwrites it. * (Setting Context 0 to aaaa::1111:2222:3333:4444 will report a 16 bit compressed address of aaaa::1111:22ff:fe33:xxxx) * * Note the IPCMV6 checksum verification depends on the correct uncompressed addresses. */ /* We know destination IP address but we need to properly convert it */ uip_ip6addr(&un_server_ipaddr, un_server_ipaddr.u16[0],un_server_ipaddr.u16[1],\ un_server_ipaddr.u16[2],un_server_ipaddr.u16[3],\ un_server_ipaddr.u16[4],un_server_ipaddr.u16[5],\ un_server_ipaddr.u16[6],un_server_ipaddr.u16[7]); pst_conn = udp_new(NULL, UIP_HTONS(__SERVER_PORT), NULL); udp_bind(pst_conn, UIP_HTONS(__CLIENT_PORT)); LOG_INFO("%s", "Create connection with the server "); //uip_debug_ipaddr_print(&un_server_ipaddr); LOG_RAW("\n\r"); LOG_INFO("local/remote port %u/%u\n\r", UIP_HTONS(pst_conn->lport), UIP_HTONS(pst_conn->rport)); //printf("Set dudp timer %p\n\r",&st_et); etimer_set(&st_et, SEND_INTERVAL, _demo_udp_callback); evproc_regCallback(EVENT_TYPE_TCPIP,_demo_udp_callback); return 1; }/* demo_udp_init() */
/*---------------------------------------------------------------------------*/ static void init(void) { static uint8_t inited = 0; if(!inited) { inited = 1; evproc_regCallback(EVENT_TYPE_TCPIP,_udp_sock_callback); } }
/*----------------------------------------------------------------------------*/ uint8_t demo_udp_socket_init(void) { pst_conn = udp_new(NULL, UIP_HTONS(__CLIENT_PORT), NULL); udp_bind(pst_conn, UIP_HTONS(__SERVER_PORT)); LOG_INFO("local/remote port %u/%u\n\r", UIP_HTONS(pst_conn->lport), UIP_HTONS(pst_conn->rport)); LOG_INFO("%s\n\r", "UDP server started, waiting for connection..."); evproc_regCallback(EVENT_TYPE_TCPIP,_demo_udp_callback); return 1; }/* demo_udp_init() */
int conn_udp_sendto(const void *data, size_t len, const void *src, size_t src_len, const void *dst, size_t dst_len, int family, uint16_t sport, uint16_t dport) { int res; _send_cmd_t send_cmd; if (!send_registered) { if (evproc_regCallback(EVENT_TYPE_CONN_SEND, _output_callback) != E_SUCCESS) { return -EIO; } else { send_registered = true; } } mutex_init(&send_cmd.mutex); if ((len > (UIP_BUFSIZE - (UIP_LLH_LEN + UIP_IPUDPH_LEN))) || (len > UINT16_MAX)) { return -EMSGSIZE; } if ((dst_len > sizeof(ipv6_addr_t)) || (family != AF_INET6)) { return -EAFNOSUPPORT; } mutex_lock(&send_cmd.mutex); send_cmd.data = data; send_cmd.data_len = (uint16_t)len; if ((res = _reg_and_bind(&send_cmd.sock, NULL, NULL, sport)) < 0) { mutex_unlock(&send_cmd.mutex); return res; } udp_socket_connect(&send_cmd.sock, (uip_ipaddr_t *)dst, dport); /* can't fail at this point */ /* change to emb6 thread context */ if (evproc_putEvent(E_EVPROC_TAIL, EVENT_TYPE_CONN_SEND, &send_cmd) != E_SUCCESS) { udp_socket_close(&send_cmd.sock); mutex_unlock(&send_cmd.mutex); return -EIO; } /* block thread until data was send */ mutex_lock(&send_cmd.mutex); udp_socket_close(&send_cmd.sock); mutex_unlock(&send_cmd.mutex); return send_cmd.res; }
int sock_udp_send(sock_udp_t *sock, const void *data, size_t len, const sock_udp_ep_t *remote) { struct udp_socket tmp; _send_cmd_t send_cmd = { .block = MUTEX_INIT, .remote = remote, .data = data, .len = len }; assert((sock != NULL) || (remote != NULL)); assert((len == 0) || (data != NULL)); /* (len != 0) => (data != NULL) */ /* we want the send in the uip thread (which udp_socket_send does not offer) * so we need to do it manually */ if (!send_registered) { if (evproc_regCallback(EVENT_TYPE_SOCK_SEND, _output_callback) != E_SUCCESS) { return -ENOMEM; } else { send_registered = true; } } if ((len > (UIP_BUFSIZE - (UIP_LLH_LEN + UIP_IPUDPH_LEN))) || (len > UINT16_MAX)) { return -ENOMEM; } if (remote != NULL) { if (remote->family != AF_INET6) { return -EAFNOSUPPORT; } if (remote->port == 0) { return -EINVAL; } send_cmd.remote = remote; } else if (sock->sock.udp_conn->rport == 0) { return -ENOTCONN; } /* cppcheck-supress nullPointerRedundantCheck * remote == NULL implies that sock != NULL (see assert at start of * function) * that's why it is okay in the if-statement above to check * sock->... without checking (sock != NULL) first => this check afterwards * isn't redundant */ if (sock == NULL) { int res; if ((res = _reg(&tmp, NULL, NULL, NULL, NULL)) < 0) { return res; } send_cmd.sock = &tmp; } else { send_cmd.sock = &sock->sock; } mutex_lock(&send_cmd.block); /* change to emb6 thread context */ if (evproc_putEvent(E_EVPROC_TAIL, EVENT_TYPE_SOCK_SEND, &send_cmd) == E_SUCCESS) { /* block thread until data was sent */ mutex_lock(&send_cmd.block); } else { /* most likely error: event queue was full */ send_cmd.res = -ENOMEM; } if (send_cmd.sock == &tmp) { udp_socket_close(&tmp); } mutex_unlock(&send_cmd.block); return send_cmd.res; }