diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/usb.mk b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/usb.mk index 32fa1fc2c..20415ddbd 100644 --- a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/usb.mk +++ b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/usb.mk @@ -42,6 +42,7 @@ INC_DIR = -I$(KERNEL_ROOT)/services/drivers/usb/ \ -I$(KERNEL_ROOT)/services/lib/memory \ -I$(KERNEL_ROOT)/services/lib/serial \ -I$(KERNEL_ROOT)/services/lib/usyscall \ + -I$(KERNEL_ROOT)/services/net/libnet \ -I$(KERNEL_ROOT)/services/boards/$(BOARD) \ -I$(KERNEL_ROOT)/services/app diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/usb/usb_service/Makefile b/Ubiquitous/XiZi_AIoT/services/drivers/usb/usb_service/Makefile index 27b53be78..3e4ac9f01 100644 --- a/Ubiquitous/XiZi_AIoT/services/drivers/usb/usb_service/Makefile +++ b/Ubiquitous/XiZi_AIoT/services/drivers/usb/usb_service/Makefile @@ -1,6 +1,7 @@ include $(KERNEL_ROOT)/services/drivers/usb/components/usb.mk objs = usb_host.o +objs += $(KERNEL_ROOT)/services/net/libnet/lwip_rndis_service.o all: ${objs} @echo "generate $^" diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/usb/usb_service/usb_host.c b/Ubiquitous/XiZi_AIoT/services/drivers/usb/usb_service/usb_host.c index 902455a1a..336b0a142 100644 --- a/Ubiquitous/XiZi_AIoT/services/drivers/usb/usb_service/usb_host.c +++ b/Ubiquitous/XiZi_AIoT/services/drivers/usb/usb_service/usb_host.c @@ -1,7 +1,9 @@ #include "usb_host.h" +#include "usb_mem.h" #include "usyscall.h" #include "libipc.h" #include "rndis_service.h" +#include "lwip_rndis_service.h" /* IPC rndis server */ int IPC_DO_SERVE_FUNC(Ipc_usbh_rndis_eth_tx)(void *dataptr, size_t *tot_len){ @@ -28,9 +30,32 @@ int ipc_rndis_server_init(void) return 0; } +/* IPC lwip client */ +struct Session *g_session_lwip = NULL; + +int ipc_lwip_client_init(void) +{ + struct Session *session; + + session = usb_malloc(sizeof(struct Session)); + if(connect_session(session, "LWIPServer", 4096) < 0) { + printf("connect session failed\n"); + return -1; + } + g_session_lwip = session; + + return 0; +} + +int lwip_rndis_data_recv(void *dataptr, size_t len) +{ + struct Session* session = g_session_lwip; + return ipc_lwip_rndis_data_recv(session, dataptr, len); +} /* usb main*/ int main(){ + ipc_lwip_client_init(); ipc_rndis_server_init(); return 0; } diff --git a/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_rndis_service.c b/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_rndis_service.c new file mode 100644 index 000000000..8228a5edd --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_rndis_service.c @@ -0,0 +1,25 @@ +/* + * 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. + */ +/************************************************* +History: +1. Date: 2024-08-14 +Author: AIIT XUOS Lab +Modification: New file lwip_rndis_service.c, in order to avoid rndis compiling other module functions. + Refer to $(KERNEL_ROOT)/services/net/libnet/lwip_service.c. +*************************************************/ +#include "lwip_rndis_service.h" + +// The interface between lwip and rndis +IPC_INTERFACE(Ipc_lwip_rndis_data_recv, 2, dataptr, len, *(size_t *)len, sizeof(size_t)); +int ipc_lwip_rndis_data_recv(struct Session* session, void *dataptr, size_t len){ + return IPC_CALL(Ipc_lwip_rndis_data_recv)(session, dataptr, &len); +} diff --git a/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_rndis_service.h b/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_rndis_service.h new file mode 100644 index 000000000..1a45bffc2 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_rndis_service.h @@ -0,0 +1,31 @@ +/* + * 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. + */ +/************************************************* +History: +1. Date: 2024-08-14 +Author: AIIT XUOS Lab +Modification: New file lwip_rndis_service.h, in order to avoid rndis compiling other module functions. + Refer to $(KERNEL_ROOT)/services/net/libnet/lwip_service.h. +*************************************************/ +#ifndef LWIP_RNDIS_SERVICE_H +#define LWIP_RNDIS_SERVICE_H + +#include "libipc.h" + +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, + Ipc_lwip_rndis_data_recv); + +// The interface between lwip and rndis +int ipc_lwip_rndis_data_recv(struct Session* session, void *dataptr, size_t len); + +#endif /* LWIP_RNDIS_SERVICE_H */ diff --git a/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_service.c b/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_service.c index c7bf12b7a..7c5df676a 100644 --- a/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_service.c +++ b/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_service.c @@ -76,3 +76,9 @@ IPC_INTERFACE(Ipc_setsockopt, 5, s, level, optname, optval, optlen, sizeof(int), int ipc_setsockopt(struct Session* session, int s, int level, int optname, void *optval, socklen_t optlen){ return IPC_CALL(Ipc_setsockopt)(session, &s, &level, &optname, optval, &optlen); } + +// The interface between lwip and rndis +IPC_INTERFACE(Ipc_lwip_rndis_data_recv, 2, dataptr, len, *(size_t *)len, sizeof(size_t)); +int ipc_lwip_rndis_data_recv(struct Session* session, void *dataptr, size_t len){ + return IPC_CALL(Ipc_lwip_rndis_data_recv)(session, dataptr, &len); +} diff --git a/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_service.h b/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_service.h index 11fa77db1..655f89ae1 100644 --- a/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_service.h +++ b/Ubiquitous/XiZi_AIoT/services/net/libnet/lwip_service.h @@ -9,12 +9,15 @@ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PSL v2 for more details. */ +#ifndef LWIP_SERVICE_H +#define LWIP_SERVICE_H #include "libipc.h" #include "lwip/sockets.h" 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) + Ipc_read, Ipc_recv, Ipc_recfrom, Ipc_sendto, Ipc_send, Ipc_write, Ipc_close, Ipc_setsockopt, + Ipc_lwip_rndis_data_recv) int ipc_socket(struct Session* session, int domain, int type, int protocol); @@ -42,3 +45,8 @@ ssize_t ipc_write(struct Session* session, int s, 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, void *optval, socklen_t optlen); + +// The interface between lwip and rndis +int ipc_lwip_rndis_data_recv(struct Session* session, void *dataptr, size_t len); + +#endif /* LWIP_SERVICE_H */ diff --git a/Ubiquitous/XiZi_AIoT/services/net/net_server/arch/ethernetif.c b/Ubiquitous/XiZi_AIoT/services/net/net_server/arch/ethernetif.c index 5973e0cd1..067bfe90c 100644 --- a/Ubiquitous/XiZi_AIoT/services/net/net_server/arch/ethernetif.c +++ b/Ubiquitous/XiZi_AIoT/services/net/net_server/arch/ethernetif.c @@ -26,6 +26,9 @@ #define IFNAME0 'e' #define IFNAME1 'n' +/* the lwip network interface */ +struct netif *g_netif = NULL; + /* IPC rndis client */ struct Session *g_session_rndis = NULL; @@ -137,13 +140,27 @@ static err_t low_level_output(struct netif *netif, struct pbuf *p) * packet from the interface into the pbuf. * * @param netif the lwip network interface structure for this ethernetif + * @param dataptr the received data + * @param len the length of received data * @return a pbuf filled with the received packet (including MAC header) * NULL on memory error */ -static struct pbuf* low_level_input(struct netif *netif) +static struct pbuf* low_level_input(struct netif *netif, void *dataptr, size_t len) { - struct pbuf *p=NULL, *q=NULL; - return p; + struct pbuf *p=NULL, *q=NULL; + int payload_offset = 0; + + /* allocate buffer */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); //cherryusb 0.10.2 + if (p != NULL) { + for (q = p; q != NULL; q = q->next) { + /* Copy the received frame into buffer from memory pointed by the current ETHERNET DMA Rx descriptor */ + memcpy(q->payload, dataptr + payload_offset, q->len); + payload_offset += q->len; + } + } + + return p; } /** @@ -154,13 +171,15 @@ static struct pbuf* low_level_input(struct netif *netif) * the appropriate input function is called. * * @param netif the lwip network interface structure for this ethernetif + * @param dataptr the received data + * @param len the length of received data */ -void ethernetif_input(struct netif *netif) +void ethernetif_input(struct netif *netif, void *dataptr, size_t len) { struct pbuf *p; /* move received packet into a new pbuf */ - p = low_level_input(netif); + p = low_level_input(netif, dataptr, len); /* if no packet could be read, silently ignore this */ if (p != NULL) { /* pass all packets to ethernet_input, which decides what packets it supports */ @@ -172,6 +191,22 @@ void ethernetif_input(struct netif *netif) } } +/** + * This function should be called when a packet is ready to be read + * from the interface. It uses the function ethernetif_input() that + * should handle the received data. + * + * @param dataptr received data + * @param len length of received data + * @return lwIP error code + */ +int lwip_rndis_data_recv(void *dataptr, size_t len) +{ + struct netif *netif = g_netif; + ethernetif_input(netif, dataptr, len); + return ERR_OK; +} + /** * In this function, get session info. * Called from ethernetif_init(). @@ -233,7 +268,10 @@ err_t ethernetif_init(struct netif *netif) /* initialize the hardware */ low_level_init(netif); + g_netif = netif; + ipc_rndis_client_init(); + return ERR_OK; } diff --git a/Ubiquitous/XiZi_AIoT/services/net/net_server/arch/ethernetif.h b/Ubiquitous/XiZi_AIoT/services/net/net_server/arch/ethernetif.h index 98a576b0a..c5e649636 100644 --- a/Ubiquitous/XiZi_AIoT/services/net/net_server/arch/ethernetif.h +++ b/Ubiquitous/XiZi_AIoT/services/net/net_server/arch/ethernetif.h @@ -17,6 +17,6 @@ #define NETIF_ENET_INIT_FUNC ethernetif_init err_t ethernetif_init(struct netif *netif); -void ethernetif_input(struct netif *netif); +int lwip_rndis_data_recv(void *dataptr, size_t len); #endif 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 12757e45d..d0e9b7077 100644 --- a/Ubiquitous/XiZi_AIoT/services/net/net_server/lwip_server.c +++ b/Ubiquitous/XiZi_AIoT/services/net/net_server/lwip_server.c @@ -21,6 +21,7 @@ #include "netif/ethernet.h" #include "sys_arch.h" #include "lwip/sockets.h" +#include "arch/ethernetif.h" extern struct netif gnetif; @@ -89,6 +90,10 @@ int IPC_DO_SERVE_FUNC(Ipc_setsockopt)(int *s, int *level, int *optname, const vo return setsockopt(*s, *level, *optname, optval, *optlen); } +// The interface between lwip and rndis +int IPC_DO_SERVE_FUNC(Ipc_lwip_rndis_data_recv)(void *dataptr, size_t *len){ + return lwip_rndis_data_recv(dataptr, *len); +} IPC_SERVER_INTERFACE(Ipc_socket, 3); IPC_SERVER_INTERFACE(Ipc_bind, 3); @@ -103,6 +108,8 @@ IPC_SERVER_INTERFACE(Ipc_send, 4); IPC_SERVER_INTERFACE(Ipc_write, 3); IPC_SERVER_INTERFACE(Ipc_close, 1); IPC_SERVER_INTERFACE(Ipc_setsockopt, 5); +// The interface between lwip and rndis +IPC_SERVER_INTERFACE(Ipc_lwip_rndis_data_recv, 2); IPC_SERVER_REGISTER_INTERFACES(IpcLWIPServer, 12, Ipc_socket, @@ -117,7 +124,8 @@ IPC_SERVER_REGISTER_INTERFACES(IpcLWIPServer, 12, Ipc_send, Ipc_write, Ipc_close, - Ipc_setsockopt); + Ipc_setsockopt, + Ipc_lwip_rndis_data_recv); int main(int argc, char* argv[]){ char lwip_ipaddr[4] = { 192, 168, 130, 77 };