api_msg.h <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< /* IP addresses and port numbers are expected to be in * the same byte order as in the corresponding pcb. */ struct api_msg_msg { struct netconn *conn; union { struct netbuf *b; /* do_send */ struct { u8_t proto; } n; /* do_newconn */ struct { struct ip_addr *ipaddr; u16_t port; } bc; /* do_bind, do_connect */ struct { struct ip_addr *ipaddr; u16_t* port; u8_t local; } ad; /* do_gettcpaddr */ struct { const void *dataptr; int len; u8_t apiflags; } w; /* do_write */ struct { u16_t len; } r; /* do_recv */ #if LWIP_IGMP struct { struct ip_addr *multiaddr; struct ip_addr *interface; enum netconn_igmp join_or_leave; } jl; /* do_join_leave_group */ #endif /* LWIP_IGMP */ } msg; }; ... void do_gettcpaddr ( struct api_msg_msg *msg); ... api_lib.c <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< /** * @todo comment */ err_t netconn_gettcpaddr(struct netconn *conn, struct ip_addr *addr, u16_t *port, u8_t local) { struct api_msg msg; msg.function = do_gettcpaddr; msg.msg.conn = conn; msg.msg.msg.ad.ipaddr = addr; msg.msg.msg.ad.port = port; msg.msg.msg.ad.local = local; TCPIP_APIMSG(&msg); return conn->err; } /** * Get the current perr a netconn is connected to. * This might only be temporary for UDP netconns, * doesn't work for RAW netconns and returns garbage * if called for a TCP listen netconn. * * @param conn the netconn to query * @param addr a pointer to which to save the remote IP address * @param port a pointer to which to save the remote port * @return ERR_CONN for invalid connections * ERR_OK if the information was retrieved */ err_t netconn_peer(struct netconn *conn, struct ip_addr *addr, u16_t *port) { LWIP_ERROR("netconn_peer: invalid conn", (conn != NULL), return ERR_ARG;); LWIP_ERROR("netconn_peer: invalid addr", (addr != NULL), return ERR_ARG;); LWIP_ERROR("netconn_peer: invalid port", (port != NULL), return ERR_ARG;); switch (NETCONNTYPE_GROUP(conn->type)) { #if LWIP_RAW case NETCONN_RAW: /* return an error as connecting is only a helper for upper layers */ return ERR_CONN; #endif /* LWIP_RAW */ #if LWIP_UDP case NETCONN_UDP: if ((conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) return ERR_CONN; *addr = conn->pcb.udp->remote_ip; *port = conn->pcb.udp->remote_port; break; #endif /* LWIP_UDP */ #if LWIP_TCP case NETCONN_TCP: return netconn_gettcpaddr( conn, addr, port, 0/*remote*/); #endif /* LWIP_TCP */ } return ERR_OK; } /** * Get the local IP address and port of a netconn. * For RAW netconns, this returns the protocol instead of a port! * * @param conn the netconn to query * @param addr a pointer to which to save the local IP address * @param port a pointer to which to save the local port (or protocol for RAW) * @return ERR_CONN for invalid connections * ERR_OK if the information was retrieved */ err_t netconn_addr(struct netconn *conn, struct ip_addr *addr, u16_t *port) { LWIP_ERROR("netconn_addr: invalid conn", (conn != NULL), return ERR_ARG;); LWIP_ERROR("netconn_addr: invalid addr", (addr != NULL), return ERR_ARG;); LWIP_ERROR("netconn_addr: invalid port", (port != NULL), return ERR_ARG;); switch (NETCONNTYPE_GROUP(conn->type)) { #if LWIP_RAW case NETCONN_RAW: *addr = conn->pcb.raw->local_ip; *port = conn->pcb.raw->protocol; break; #endif /* LWIP_RAW */ #if LWIP_UDP case NETCONN_UDP: *addr = conn->pcb.udp->local_ip; *port = conn->pcb.udp->local_port; break; #endif /* LWIP_UDP */ #if LWIP_TCP case NETCONN_TCP: return netconn_gettcpaddr( conn, addr, port, 1/*local*/); #endif /* LWIP_TCP */ } return ERR_OK; } api_msg.c <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< void do_gettcpaddr(struct api_msg_msg *msg) { if (msg->conn->pcb.tcp != NULL) { #if LWIP_TCP if (msg->msg.ad.local) { *(msg->msg.ad.ipaddr) = msg->conn->pcb.tcp->local_ip; *(msg->msg.ad.port) = msg->conn->pcb.tcp->local_port; } else { *(msg->msg.ad.ipaddr) = msg->conn->pcb.tcp->remote_ip; *(msg->msg.ad.port) = msg->conn->pcb.tcp->remote_port; } #endif /* LWIP_TCP */ } else { msg->conn->err = ERR_CONN; } TCPIP_APIMSG_ACK(msg); }