From 43bb298df9a655124786b73a92fecb6964beafc6 Mon Sep 17 00:00:00 2001 From: lr <1234@qq.com> Date: Wed, 22 May 2024 18:05:50 +0800 Subject: [PATCH] warp the socket api --- Ubiquitous/XiZi_AIoT/services/app/test_net.c | 1 - .../net/console_eth_driver/ethernetif.c | 186 ++++++++++++++++++ .../services/net/libnet/lwip_service.c | 66 ++++++- .../services/net/libnet/lwip_service.h | 32 ++- .../services/net/net_server/lwip_server.c | 95 ++++++++- 5 files changed, 368 insertions(+), 12 deletions(-) create mode 100644 Ubiquitous/XiZi_AIoT/services/net/console_eth_driver/ethernetif.c diff --git a/Ubiquitous/XiZi_AIoT/services/app/test_net.c b/Ubiquitous/XiZi_AIoT/services/app/test_net.c index c21192f59..d05b44fc7 100644 --- a/Ubiquitous/XiZi_AIoT/services/app/test_net.c +++ b/Ubiquitous/XiZi_AIoT/services/app/test_net.c @@ -23,7 +23,6 @@ int main(int argc, char* argv[]) struct Session sess; connect_session(&sess, "LWIPServer", 4096); - LWIP_test(&sess); free_session(&sess); diff --git a/Ubiquitous/XiZi_AIoT/services/net/console_eth_driver/ethernetif.c b/Ubiquitous/XiZi_AIoT/services/net/console_eth_driver/ethernetif.c new file mode 100644 index 000000000..93e721963 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/net/console_eth_driver/ethernetif.c @@ -0,0 +1,186 @@ + +/* + * Copyright (c) 2020 AIIT XUOS Lab + * XiUOS is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "lwip/ethip6.h" +#include "lwip/etharp.h" +#include "libserial.h" +/* Define those to better describe your network interface. */ +#define IFNAME0 'e' +#define IFNAME1 'n' + +/** + * In this function, the hardware should be initialized. + * Called from ethernetif_init(). + * + * @param netif the already initialized lwip network interface structure + * for this ethernetif + */ +static void +low_level_init(struct netif *netif) +{ +#if LWIP_ARP || LWIP_ETHERNET + + /* set MAC hardware address length */ + netif->hwaddr_len = ETH_HWADDR_LEN; + + /* set MAC hardware address */ + netif->hwaddr[0] = 0x02; + netif->hwaddr[1] = 0x12; + netif->hwaddr[2] = 0x34; + netif->hwaddr[3] = 0x56; + netif->hwaddr[4] = 0x78; + netif->hwaddr[5] = 0xab; + netif->hwaddr_len = 6; + + /* maximum transfer unit */ + netif->mtu = 1500; + +#if LWIP_ARP + netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; +#else + netif->flags |= NETIF_FLAG_BROADCAST; +#endif /* LWIP_ARP */ + +#endif /* LWIP_ARP || LWIP_ETHERNET */ + +} + +/** + * This function should do the actual transmission of the packet. The packet is + * contained in the pbuf that is passed to the function. This pbuf + * might be chained. + * + * @param netif the lwip network interface structure for this ethernetif + * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) + * @return ERR_OK if the packet could be sent + * an err_t value if the packet couldn't be sent + * + * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to + * strange results. You might consider waiting for space in the DMA queue + * to become available since the stack doesn't retry to send a packet + * dropped because of memory failure (except for the TCP timers). + */ + +static err_t +low_level_output(struct netif *netif, struct pbuf *p) +{ + char buf[1518]; +#if ETH_PAD_SIZE + pbuf_remove_header(p, ETH_PAD_SIZE); /* drop the padding word */ +#endif + + pbuf_copy_partial(p, buf, p->tot_len, 0); + + printf("output %s\n", buf); + return ERR_OK; +} + +/** + * Should allocate a pbuf and transfer the bytes of the incoming + * packet from the interface into the pbuf. + * + * @param netif the lwip network interface structure for this ethernetif + * @return a pbuf filled with the received packet (including MAC header) + * NULL on memory error + */ +static struct pbuf* low_level_input(struct netif *netif) +{ + struct pbuf *p, *q; + + + return p; +} + +/** + * This function should be called when a packet is ready to be read + * from the interface. It uses the function low_level_input() that + * should handle the actual reception of bytes from the network + * interface. Then the type of the received packet is determined and + * the appropriate input function is called. + * + * @param netif the lwip network interface structure for this ethernetif + */ +static void +ethernetif_input(struct netif *netif) +{ + struct ethernetif *ethernetif; + struct eth_hdr *ethhdr; + struct pbuf *p; + + ethernetif = netif->state; + + /* move received packet into a new pbuf */ + p = low_level_input(netif); + /* if no packet could be read, silently ignore this */ + if (p != NULL) { + /* pass all packets to ethernet_input, which decides what packets it supports */ + if (netif->input(p, netif) != ERR_OK) { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); + pbuf_free(p); + p = NULL; + } + } +} + +/** + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + * any other err_t on error + */ +err_t +ethernetif_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + netif->hostname = "lwip"; +#endif /* LWIP_NETIF_HOSTNAME */ + + /* + * Initialize the snmp variables and counters inside the struct netif. + * The last argument should be replaced with your link speed, in units + * of bits per second. + */ + MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, 100000000); + + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; +#if LWIP_IPV4 + netif->output = etharp_output; +#endif /* LWIP_IPV4 */ +#if LWIP_IPV6 + netif->output_ip6 = ethip6_output; +#endif /* LWIP_IPV6 */ + netif->linkoutput = low_level_output; + + /* initialize the hardware */ + low_level_init(netif); + + return ERR_OK; +} + + diff --git a/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_service.c b/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_service.c index 541e6fb0d..312d464a5 100644 --- a/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_service.c +++ b/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_service.c @@ -12,9 +12,67 @@ #include "lwip_service.h" #include -IPC_INTERFACE(Ipc_LWIP_test, 1, ignore, sizeof(int)) -void LWIP_test(struct Session* session){ - IPC_CALL(Ipc_LWIP_test)(session, NULL); +IPC_INTERFACE(Ipc_socket, 3, domain, type, protocol, sizeof(int), sizeof(int), sizeof(int)); +int ipc_socket(struct Session* session, int domain, int type, int protocol){ + return IPC_CALL(Ipc_socket)(session, &domain, &type, &protocol); } - \ No newline at end of file +IPC_INTERFACE(Ipc_bind, 3, s, name, namelen, sizeof(int), sizeof(struct sockaddr), sizeof(socklen_t)); +int ipc_bind(struct Session* session, int s, const struct sockaddr *name, socklen_t namelen){ + return IPC_CALL(Ipc_bind)(session, &s, name, &namelen); +} + +IPC_INTERFACE(Ipc_connect, 3, s, name, namelen, sizeof(int), sizeof(struct sockaddr), sizeof(socklen_t)); +int ipc_connect(struct Session* session, int s, const struct sockaddr *name, socklen_t namelen){ + return IPC_CALL(Ipc_connect)(session, &s, name, &namelen); +} + +IPC_INTERFACE(Ipc_listen, 2, s, backlog, sizeof(int), sizeof(int)); +int ipc_listen(struct Session* session, int s, int backlog){ + return IPC_CALL(Ipc_listen)(session, &s, &backlog); +} + +IPC_INTERFACE(Ipc_accept, 3, s, addr, addlen, sizeof(int), sizeof(struct sockaddr), sizeof(socklen_t)); +int ipc_accept(struct Session* session, int s, struct sockaddr *addr, socklen_t *addrlen){ + return IPC_CALL(Ipc_accept)(session, &s, addr, addrlen); +} + +IPC_INTERFACE(Ipc_read, 3, s, mem, len, sizeof(int), *(size_t *)len, sizeof(size_t)); +ssize_t ipc_read(struct Session* session, int s, void *mem, size_t len) { + return IPC_CALL(Ipc_read)(session, &s, mem, &len); +} + +IPC_INTERFACE(Ipc_recv, 4, s, mem, len, flags, sizeof(int), *(size_t *)len, sizeof(size_t), sizeof(int)); +ssize_t ipc_recv(struct Session* session, int s, void *mem, size_t len, int flags){ + return IPC_CALL(Ipc_recv)(session, &s, mem, &len, &flags); +} + +IPC_INTERFACE(Ipc_recfrom, 6, s, mem, len, flags, from, fromlen, sizeof(int), *(size_t *)len, sizeof(size_t), sizeof(int), sizeof(struct sockaddr), sizeof(socklen_t)); +ssize_t ipc_recvfrom(struct Session* session, int s, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen){ + return IPC_CALL(Ipc_recfrom)(session, &s, mem, &len, &flags, from, fromlen); +} + +IPC_INTERFACE(Ipc_sendto, 6, s, data, size, flags, to, tolen, sizeof(int), *(size_t *)size, sizeof(size_t), sizeof(int), sizeof(struct sockaddr), sizeof(socklen_t)); +ssize_t ipc_sendto(struct Session* session, int s, const void *data, size_t size, int flags, const struct sockaddr *to, socklen_t tolen){ + return IPC_CALL(Ipc_sendto)(session, &s, data, &size, &flags, to, &tolen); +} + +IPC_INTERFACE(Ipc_send, 4, s, data, size, flags, sizeof(int), *(size_t *)size, sizeof(size_t), sizeof(int)); +ssize_t ipc_send(struct Session* session, int s, const void *data, size_t size, int flags){ + return IPC_CALL(Ipc_send)(session, &s, data, &size, &flags); +} + +IPC_INTERFACE(Ipc_write, 3, s, data, size, sizeof(int), *(size_t *)size, sizeof(size_t)); +ssize_t ipc_write(struct Session* session, int s, const void *data, size_t size){ + return IPC_CALL(Ipc_write)(session, &s, data, &size); +} + +IPC_INTERFACE(Ipc_close, 1, s, sizeof(int)); +int ipc_close(struct Session* session, int s){ + return IPC_CALL(Ipc_close)(session, &s); +} + +IPC_INTERFACE(Ipc_setsockopt, 5, s, level, optname, optval, optlen, sizeof(int), sizeof(int), sizeof(int), *(socklen_t*)optlen, sizeof(socklen_t)); +int ipc_setsockopt(struct Session* session, int s, int level, int optname, const void *optval, socklen_t optlen){ + return IPC_CALL(Ipc_setsockopt)(session, &s, &level, &optname, optval, &optlen); +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_service.h b/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_service.h index 17d8ab300..bd8dc71ce 100644 --- a/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_service.h +++ b/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_service.h @@ -11,7 +11,35 @@ */ #include "libipc.h" +#include "lwip/sockets.h" -IPC_SERVICES(IpcLWIPServer, Ipc_LWIP_test) +IPC_SERVICES(IpcLWIPServer, Ipc_socket, Ipc_bind,Ipc_connect,Ipc_listen,Ipc_accept, + Ipc_read, Ipc_recv, Ipc_recfrom, Ipc_sendto, Ipc_send, Ipc_write, Ipc_close, Ipc_setsockopt) -void LWIP_test(struct Session* session); +int ipc_socket(struct Session* session, + int domain, int type, int protocol); + +int ipc_bind(struct Session* session, int s, + const struct sockaddr *name, socklen_t namelen); + +int ipc_connect(struct Session* session, int s, const struct sockaddr *name, socklen_t namelen); + +int ipc_listen(struct Session* session, int s, int backlog); + +int ipc_accept(struct Session* session, int s, struct sockaddr *addr, socklen_t *addrlen); + +ssize_t ipc_read(struct Session* session, int s, void *mem, size_t len); + +ssize_t ipc_recv(struct Session* session, int s, void *mem, size_t len, int flags); + +ssize_t ipc_recvfrom(struct Session* session, int s, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen); + +ssize_t ipc_sendto(struct Session* session, int s, const void *data, size_t size, int flags, const struct sockaddr *to, socklen_t tolen); + +ssize_t ipc_send(struct Session* session, int s, const void *data, size_t size, int flags); + +ssize_t ipc_write(struct Session* session, int s, const void *data, size_t size); + +int ipc_close(struct Session* session, int s); + +int ipc_setsockopt(struct Session* session, int s, int level, int optname, const void *optval, socklen_t optlen); diff --git a/Ubiquitous/XiZi_AIoT/services/net/net_server/lwip_server.c b/Ubiquitous/XiZi_AIoT/services/net/net_server/lwip_server.c index 8d2ee21bd..4664d81c5 100644 --- a/Ubiquitous/XiZi_AIoT/services/net/net_server/lwip_server.c +++ b/Ubiquitous/XiZi_AIoT/services/net/net_server/lwip_server.c @@ -20,16 +20,101 @@ #include "lwip/netif.h" #include "netif/ethernet.h" #include "sys_arch.h" +#include "lwip/sockets.h" +extern struct netif gnetif; -int IPC_DO_SERVE_FUNC(Ipc_LWIP_test)(struct Session* session){ - printf("LWIP init success"); - return 1; +int IPC_DO_SERVE_FUNC(Ipc_socket)(int *domain, int *type, int *protocol){ + return socket(*domain, *type, *protocol); +} + +int IPC_DO_SERVE_FUNC(Ipc_bind)(int *s, const struct sockaddr *name, socklen_t *namelen){ + return bind(*s, name, *namelen); +} + +int IPC_DO_SERVE_FUNC(Ipc_connect)(int* s, const struct sockaddr* name, socklen_t* namelen){ + return connect(*s, name, *namelen); +} + +// int serve_accept(struct Session* session, int *s, struct sockaddr *addr, socklen_t *addrlen) { +// session_finish_handle(session, accept(*s, addr, addrlen)); +// exit(0); +// return 0; +// } + +// static char accept_thread[] = "accept_thread"; +int IPC_DO_SERVE_FUNC(Ipc_accept)(int* s, struct sockaddr* addr, socklen_t* addrlen){ + // if(!is_cur_handler_been_delayed()) { + // char* param[] = {s, addr, addrlen, NULL}; + // if(thread(serve_accept, accept_thread, param) < 0) { + // return -1; + // } + // } + // delay_session(); + return accept(*s, addr, addrlen); +} + +int IPC_DO_SERVE_FUNC(Ipc_read)(int* s, void* mem, size_t* len){ + return read(*s, mem, *len); +} + +int IPC_DO_SERVE_FUNC(Ipc_recv)(int* s, void* mem, size_t* len, int* flags){ + return recv(*s, mem, *len, *flags); +} + +int IPC_DO_SERVE_FUNC(Ipc_recfrom)(int* s, void *mem, size_t* len, int* flags, struct sockaddr* from, socklen_t* fromlen){ + return recvfrom(*s, mem, *len, *flags, from, fromlen); } -IPC_SERVER_INTERFACE(Ipc_LWIP_test, 1); -IPC_SERVER_REGISTER_INTERFACES(IpcLWIPServer, 1, Ipc_LWIP_test); +int IPC_DO_SERVE_FUNC(Ipc_sendto)(int *s, const void *data, size_t *size, int *flags, const struct sockaddr *to, socklen_t *tolen){ + return sendto(*s, data, *size, *flags, to, *tolen); +} + +int IPC_DO_SERVE_FUNC(Ipc_send)(int *s, const void *data, size_t *size, int *flags){ + return send(*s, data, *size, *flags); +} + +int IPC_DO_SERVE_FUNC(Ipc_write)(int *s, const void *data, size_t *size){ + return write(*s, data, *size); +} + +int IPC_DO_SERVE_FUNC(Ipc_close)(int *s){ + return close(*s); +} +int IPC_DO_SERVE_FUNC(Ipc_setsockopt)(int *s, int *level, int *optname, const void *optval, socklen_t *optlen){ + return setsockopt(*s, *level, *optname, optval, *optlen); +} + + +IPC_SERVER_INTERFACE(Ipc_socket, 3); +IPC_SERVER_INTERFACE(Ipc_bind, 3); +IPC_SERVER_INTERFACE(Ipc_connect, 3); +IPC_SERVER_INTERFACE(Ipc_listen, 2); +IPC_SERVER_INTERFACE(Ipc_accept, 3); +IPC_SERVER_INTERFACE(Ipc_read, 3); +IPC_SERVER_INTERFACE(Ipc_recv, 4); +IPC_SERVER_INTERFACE(Ipc_recfrom, 6); +IPC_SERVER_INTERFACE(Ipc_sendto, 6); +IPC_SERVER_INTERFACE(Ipc_send, 4); +IPC_SERVER_INTERFACE(Ipc_write, 3); +IPC_SERVER_INTERFACE(Ipc_close, 1); +IPC_SERVER_INTERFACE(Ipc_setsockopt, 5); + +IPC_SERVER_REGISTER_INTERFACES(IpcLWIPServer, 12, + Ipc_socket, + Ipc_bind, + Ipc_connect, + Ipc_listen, + Ipc_accept, + Ipc_read, + Ipc_recv, + Ipc_recfrom, + Ipc_sendto, + Ipc_send, + Ipc_write, + Ipc_close, + Ipc_setsockopt); int main(int argc, char* argv[]){ char lwip_ipaddr[4] = { 192, 168, 130, 77 };