13d8536b4Sopenharmony_ci/* 23d8536b4Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 33d8536b4Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. 43d8536b4Sopenharmony_ci * 53d8536b4Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification, 63d8536b4Sopenharmony_ci * are permitted provided that the following conditions are met: 73d8536b4Sopenharmony_ci * 83d8536b4Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of 93d8536b4Sopenharmony_ci * conditions and the following disclaimer. 103d8536b4Sopenharmony_ci * 113d8536b4Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list 123d8536b4Sopenharmony_ci * of conditions and the following disclaimer in the documentation and/or other materials 133d8536b4Sopenharmony_ci * provided with the distribution. 143d8536b4Sopenharmony_ci * 153d8536b4Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used 163d8536b4Sopenharmony_ci * to endorse or promote products derived from this software without specific prior written 173d8536b4Sopenharmony_ci * permission. 183d8536b4Sopenharmony_ci * 193d8536b4Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 203d8536b4Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 213d8536b4Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 223d8536b4Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 233d8536b4Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 243d8536b4Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 253d8536b4Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 263d8536b4Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 273d8536b4Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 283d8536b4Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 293d8536b4Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 303d8536b4Sopenharmony_ci */ 313d8536b4Sopenharmony_ci 323d8536b4Sopenharmony_ci#include "lwip_test.h" 333d8536b4Sopenharmony_ci#include <lwip/netif.h> 343d8536b4Sopenharmony_ci#include <lwip/netifapi.h> 353d8536b4Sopenharmony_ci#include <lwip/pbuf.h> 363d8536b4Sopenharmony_ci#include <lwip/ip4_addr.h> 373d8536b4Sopenharmony_ci#include <lwip/ip4.h> 383d8536b4Sopenharmony_ci#include <lwip/ip.h> 393d8536b4Sopenharmony_ci#include <lwip/def.h> 403d8536b4Sopenharmony_ci#include <lwip/udp.h> 413d8536b4Sopenharmony_ci#include <lwip/inet_chksum.h> 423d8536b4Sopenharmony_ci#include "lwip/prot/iana.h" 433d8536b4Sopenharmony_ci 443d8536b4Sopenharmony_ci#define MSG "Hi, I am testing BT netif." 453d8536b4Sopenharmony_ci#define STACK_IP_BT "192.168.167.1" 463d8536b4Sopenharmony_ci#define PEER_IP_BT "100.100.100.100" 473d8536b4Sopenharmony_ci#define GATEWAY_IP_BT "192.168.167.239" 483d8536b4Sopenharmony_ci#define NETIF_MAC "121212" 493d8536b4Sopenharmony_ci#define PEER_MAC "454545" 503d8536b4Sopenharmony_ci#define NETIF_NAME_BT "bt1000" 513d8536b4Sopenharmony_ci#define TEST_CASE 210 523d8536b4Sopenharmony_cistatic char g_buf[BUF_SIZE + 1] = { 0 }; 533d8536b4Sopenharmony_cistruct netif *btProxyNf = NULL; 543d8536b4Sopenharmony_ci 553d8536b4Sopenharmony_cistatic void ReplayArpTask(); 563d8536b4Sopenharmony_cistatic void ArpPackageProc(struct netif *netif, struct pbuf *p); 573d8536b4Sopenharmony_ciextern void driverif_input(struct netif *netif, struct pbuf *p); 583d8536b4Sopenharmony_cistatic void ReplayArpEncodeEthernet(struct netif *netif, struct pbuf *p); 593d8536b4Sopenharmony_ci 603d8536b4Sopenharmony_cistatic void ReplayUdpEncodeEthernet(struct netif *netif, struct pbuf *p) 613d8536b4Sopenharmony_ci{ 623d8536b4Sopenharmony_ci int ret; 633d8536b4Sopenharmony_ci ret = pbuf_add_header(p, SIZEOF_ETH_HDR); 643d8536b4Sopenharmony_ci ICUNIT_ASSERT_EQUAL(ret, 0, 1); 653d8536b4Sopenharmony_ci 663d8536b4Sopenharmony_ci struct eth_hdr *ethhdr; 673d8536b4Sopenharmony_ci ethhdr = (struct eth_hdr *)p->payload; 683d8536b4Sopenharmony_ci ethhdr->type = lwip_htons(ETHTYPE_IP); 693d8536b4Sopenharmony_ci SMEMCPY(ðhdr->dest, NETIF_MAC, ETH_HWADDR_LEN); 703d8536b4Sopenharmony_ci SMEMCPY(ðhdr->src, PEER_MAC, ETH_HWADDR_LEN); 713d8536b4Sopenharmony_ci 723d8536b4Sopenharmony_ci driverif_input(netif, p); 733d8536b4Sopenharmony_ci} 743d8536b4Sopenharmony_ci 753d8536b4Sopenharmony_cistatic void ReplayUdpEncodeIp(struct pbuf *p, ip4_addr_t *src, ip4_addr_t *dest) 763d8536b4Sopenharmony_ci{ 773d8536b4Sopenharmony_ci struct ip_hdr *iphdr; 783d8536b4Sopenharmony_ci int ret; 793d8536b4Sopenharmony_ci#if CHECKSUM_GEN_IP_INLINE 803d8536b4Sopenharmony_ci u32_t chk_sum = 0; 813d8536b4Sopenharmony_ci#endif /* CHECKSUM_GEN_IP_INLINE */ 823d8536b4Sopenharmony_ci 833d8536b4Sopenharmony_ci // ip header 843d8536b4Sopenharmony_ci ret = pbuf_add_header(p, IP_HLEN); 853d8536b4Sopenharmony_ci ICUNIT_ASSERT_EQUAL(ret, 0, 2); 863d8536b4Sopenharmony_ci iphdr = (struct ip_hdr *)p->payload; 873d8536b4Sopenharmony_ci IPH_TTL_SET(iphdr, UDP_TTL); 883d8536b4Sopenharmony_ci IPH_PROTO_SET(iphdr, IP_PROTO_UDP); 893d8536b4Sopenharmony_ci 903d8536b4Sopenharmony_ci#if CHECKSUM_GEN_IP_INLINE 913d8536b4Sopenharmony_ci chk_sum += PP_NTOHS(IP_PROTO_UDP | (ttl << 8)); 923d8536b4Sopenharmony_ci#endif /* CHECKSUM_GEN_IP_INLINE */ 933d8536b4Sopenharmony_ci 943d8536b4Sopenharmony_ci /* dest cannot be NULL here */ 953d8536b4Sopenharmony_ci ip4_addr_copy(iphdr->dest, *dest); 963d8536b4Sopenharmony_ci#if CHECKSUM_GEN_IP_INLINE 973d8536b4Sopenharmony_ci chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF; 983d8536b4Sopenharmony_ci chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16; 993d8536b4Sopenharmony_ci#endif /* CHECKSUM_GEN_IP_INLINE */ 1003d8536b4Sopenharmony_ci 1013d8536b4Sopenharmony_ci u16_t ip_hlen = IP_HLEN; 1023d8536b4Sopenharmony_ci IPH_VHL_SET(iphdr, 4, ip_hlen / 4); 1033d8536b4Sopenharmony_ci IPH_TOS_SET(iphdr, 0); 1043d8536b4Sopenharmony_ci#if CHECKSUM_GEN_IP_INLINE 1053d8536b4Sopenharmony_ci chk_sum += PP_NTOHS(tos | (iphdr->_v_hl << 8)); 1063d8536b4Sopenharmony_ci#endif /* CHECKSUM_GEN_IP_INLINE */ 1073d8536b4Sopenharmony_ci IPH_LEN_SET(iphdr, lwip_htons(p->tot_len)); 1083d8536b4Sopenharmony_ci#if CHECKSUM_GEN_IP_INLINE 1093d8536b4Sopenharmony_ci chk_sum += iphdr->_len; 1103d8536b4Sopenharmony_ci#endif /* CHECKSUM_GEN_IP_INLINE */ 1113d8536b4Sopenharmony_ci IPH_OFFSET_SET(iphdr, 0); 1123d8536b4Sopenharmony_ci IPH_ID_SET(iphdr, lwip_htons(0)); 1133d8536b4Sopenharmony_ci#if CHECKSUM_GEN_IP_INLINE 1143d8536b4Sopenharmony_ci chk_sum += iphdr->_id; 1153d8536b4Sopenharmony_ci#endif /* CHECKSUM_GEN_IP_INLINE */ 1163d8536b4Sopenharmony_ci ip4_addr_copy(iphdr->src, *src); 1173d8536b4Sopenharmony_ci 1183d8536b4Sopenharmony_ci#if CHECKSUM_GEN_IP_INLINE 1193d8536b4Sopenharmony_ci chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF; 1203d8536b4Sopenharmony_ci chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16; 1213d8536b4Sopenharmony_ci chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF); 1223d8536b4Sopenharmony_ci chk_sum = (chk_sum >> 16) + chk_sum; 1233d8536b4Sopenharmony_ci chk_sum = ~chk_sum; 1243d8536b4Sopenharmony_ci IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { 1253d8536b4Sopenharmony_ci iphdr->_chksum = (u16_t)chk_sum; /* network order */ 1263d8536b4Sopenharmony_ci } 1273d8536b4Sopenharmony_ci#if LWIP_CHECKSUM_CTRL_PER_NETIF 1283d8536b4Sopenharmony_ci else { 1293d8536b4Sopenharmony_ci IPH_CHKSUM_SET(iphdr, 0); 1303d8536b4Sopenharmony_ci } 1313d8536b4Sopenharmony_ci#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */ 1323d8536b4Sopenharmony_ci#else /* CHECKSUM_GEN_IP_INLINE */ 1333d8536b4Sopenharmony_ci IPH_CHKSUM_SET(iphdr, 0); 1343d8536b4Sopenharmony_ci#if CHECKSUM_GEN_IP 1353d8536b4Sopenharmony_ci IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { 1363d8536b4Sopenharmony_ci IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen)); 1373d8536b4Sopenharmony_ci } 1383d8536b4Sopenharmony_ci#endif /* CHECKSUM_GEN_IP */ 1393d8536b4Sopenharmony_ci#endif /* CHECKSUM_GEN_IP_INLINE */ 1403d8536b4Sopenharmony_ci 1413d8536b4Sopenharmony_ci ReplayUdpEncodeEthernet(btProxyNf, p); 1423d8536b4Sopenharmony_ci} 1433d8536b4Sopenharmony_ci 1443d8536b4Sopenharmony_cistatic void ReplayUdp(void *ptemp) 1453d8536b4Sopenharmony_ci{ 1463d8536b4Sopenharmony_ci struct udp_hdr *udphdr; 1473d8536b4Sopenharmony_ci ip4_addr_t sipaddr, dipaddr; 1483d8536b4Sopenharmony_ci int size = strlen(MSG); 1493d8536b4Sopenharmony_ci int ret; 1503d8536b4Sopenharmony_ci (void)ptemp; 1513d8536b4Sopenharmony_ci 1523d8536b4Sopenharmony_ci LogPrintln("encode udp replay packet"); 1533d8536b4Sopenharmony_ci inet_pton(AF_INET, PEER_IP_BT, &sipaddr); 1543d8536b4Sopenharmony_ci inet_pton(AF_INET, STACK_IP_BT, &dipaddr); 1553d8536b4Sopenharmony_ci 1563d8536b4Sopenharmony_ci struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM); 1573d8536b4Sopenharmony_ci u16_t chksum = LWIP_CHKSUM_COPY(p->payload, MSG, size); 1583d8536b4Sopenharmony_ci 1593d8536b4Sopenharmony_ci // udp header 1603d8536b4Sopenharmony_ci ret = pbuf_add_header(p, UDP_HLEN); 1613d8536b4Sopenharmony_ci ICUNIT_ASSERT_EQUAL(ret, 0, 1); 1623d8536b4Sopenharmony_ci udphdr = (struct udp_hdr *)p->payload; 1633d8536b4Sopenharmony_ci udphdr->src = lwip_htons(STACK_PORT); 1643d8536b4Sopenharmony_ci udphdr->dest = lwip_htons(STACK_PORT); 1653d8536b4Sopenharmony_ci udphdr->len = lwip_htons(p->tot_len); 1663d8536b4Sopenharmony_ci /* in UDP, 0 checksum means 'no checksum' */ 1673d8536b4Sopenharmony_ci u16_t udpchksum = ip_chksum_pseudo_partial(p, IP_PROTO_UDP, p->tot_len, UDP_HLEN, &sipaddr, &dipaddr); 1683d8536b4Sopenharmony_ci u32_t acc = udpchksum + (u16_t)~(chksum); 1693d8536b4Sopenharmony_ci udpchksum = FOLD_U32T(acc); 1703d8536b4Sopenharmony_ci if (udpchksum == 0x0000) { 1713d8536b4Sopenharmony_ci udpchksum = 0xffff; 1723d8536b4Sopenharmony_ci } 1733d8536b4Sopenharmony_ci udphdr->chksum = udpchksum; 1743d8536b4Sopenharmony_ci udphdr->chksum = 0; 1753d8536b4Sopenharmony_ci 1763d8536b4Sopenharmony_ci ReplayUdpEncodeIp(p, &sipaddr, &dipaddr); 1773d8536b4Sopenharmony_ci} 1783d8536b4Sopenharmony_ci 1793d8536b4Sopenharmony_cistatic void ReplayUdpTask() 1803d8536b4Sopenharmony_ci{ 1813d8536b4Sopenharmony_ci int ret; 1823d8536b4Sopenharmony_ci ret = sys_thread_new("replay_udp", ReplayUdp, NULL, 1833d8536b4Sopenharmony_ci STACK_TEST_SIZE, TCPIP_THREAD_PRIO); 1843d8536b4Sopenharmony_ci ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 3); 1853d8536b4Sopenharmony_ci} 1863d8536b4Sopenharmony_ci 1873d8536b4Sopenharmony_cistatic void ParsePackageIpUdp(struct netif *netif, struct pbuf *btBuf) 1883d8536b4Sopenharmony_ci{ 1893d8536b4Sopenharmony_ci // get scr_addr and dest_addr from ip head 1903d8536b4Sopenharmony_ci const struct ip_hdr *iphdr; 1913d8536b4Sopenharmony_ci iphdr = (const struct ip_hdr *)btBuf->payload; 1923d8536b4Sopenharmony_ci ip4_addr_p_t ip4_addr_scr = iphdr->src; 1933d8536b4Sopenharmony_ci ip4_addr_p_t ip4_addr_dest = iphdr->dest; 1943d8536b4Sopenharmony_ci char buf[32]; 1953d8536b4Sopenharmony_ci int dataLen; 1963d8536b4Sopenharmony_ci 1973d8536b4Sopenharmony_ci // get scr_port and dest port from tcp head 1983d8536b4Sopenharmony_ci u16_t scr_port, dest_port; 1993d8536b4Sopenharmony_ci void *data; 2003d8536b4Sopenharmony_ci struct udp_hdr *udphdr; 2013d8536b4Sopenharmony_ci udphdr = (struct udp_hdr *)((u8_t *)iphdr + IPH_HL_BYTES(iphdr)); 2023d8536b4Sopenharmony_ci scr_port = udphdr->src; 2033d8536b4Sopenharmony_ci dest_port = udphdr->dest; 2043d8536b4Sopenharmony_ci data = (void *)((u8_t *)udphdr + UDP_HLEN); 2053d8536b4Sopenharmony_ci 2063d8536b4Sopenharmony_ci LogPrintln("======Bt netif send package======"); 2073d8536b4Sopenharmony_ci LogPrintln("netif full name %s", netif->full_name); 2083d8536b4Sopenharmony_ci (void)inet_ntop(AF_INET, &ip4_addr_scr.addr, buf, sizeof(buf)); 2093d8536b4Sopenharmony_ci LogPrintln("package src ip %s", buf); 2103d8536b4Sopenharmony_ci (void)inet_ntop(AF_INET, &ip4_addr_dest.addr, buf, sizeof(buf)); 2113d8536b4Sopenharmony_ci LogPrintln("package dest ip %s", buf); 2123d8536b4Sopenharmony_ci LogPrintln("package src port %d", lwip_ntohs(scr_port)); 2133d8536b4Sopenharmony_ci LogPrintln("package dest port %d", lwip_ntohs(dest_port)); 2143d8536b4Sopenharmony_ci LogPrintln("send data %s", (char *)data); 2153d8536b4Sopenharmony_ci dataLen = lwip_ntohs(udphdr->len) - UDP_HLEN; 2163d8536b4Sopenharmony_ci LogPrintln("send data length %d", dataLen); 2173d8536b4Sopenharmony_ci ICUNIT_ASSERT_EQUAL(dataLen, strlen(MSG), 4); 2183d8536b4Sopenharmony_ci LogPrintln("================================="); 2193d8536b4Sopenharmony_ci 2203d8536b4Sopenharmony_ci ReplayUdpTask(); 2213d8536b4Sopenharmony_ci} 2223d8536b4Sopenharmony_ci 2233d8536b4Sopenharmony_cistatic void ParsePackageEthernet(struct netif *netif, struct pbuf *p) 2243d8536b4Sopenharmony_ci{ 2253d8536b4Sopenharmony_ci u16_t next_hdr_offset = SIZEOF_ETH_HDR; 2263d8536b4Sopenharmony_ci // get src mac and dest mac 2273d8536b4Sopenharmony_ci struct eth_hdr *ethhdr; 2283d8536b4Sopenharmony_ci ethhdr = (struct eth_hdr *)p->payload; 2293d8536b4Sopenharmony_ci u16_t type = ethhdr->type; 2303d8536b4Sopenharmony_ci 2313d8536b4Sopenharmony_ci switch (type) { 2323d8536b4Sopenharmony_ci#if LWIP_IPV4 && LWIP_ARP 2333d8536b4Sopenharmony_ci /* IP packet? */ 2343d8536b4Sopenharmony_ci case PP_HTONS(ETHTYPE_IP): // 0x0008 2353d8536b4Sopenharmony_ci if (!(netif->flags & NETIF_FLAG_ETHARP)) { 2363d8536b4Sopenharmony_ci return; 2373d8536b4Sopenharmony_ci } 2383d8536b4Sopenharmony_ci /* skip Ethernet header (min. size checked above) */ 2393d8536b4Sopenharmony_ci if (pbuf_remove_header(p, next_hdr_offset)) { 2403d8536b4Sopenharmony_ci return; 2413d8536b4Sopenharmony_ci } else { 2423d8536b4Sopenharmony_ci /* pass to IP layer */ 2433d8536b4Sopenharmony_ci ParsePackageIpUdp(netif, p); 2443d8536b4Sopenharmony_ci } 2453d8536b4Sopenharmony_ci break; 2463d8536b4Sopenharmony_ci 2473d8536b4Sopenharmony_ci case PP_HTONS(ETHTYPE_ARP): // 0x0608 2483d8536b4Sopenharmony_ci if (!(netif->flags & NETIF_FLAG_ETHARP)) { 2493d8536b4Sopenharmony_ci return; 2503d8536b4Sopenharmony_ci } 2513d8536b4Sopenharmony_ci /* skip Ethernet header (min. size checked above) */ 2523d8536b4Sopenharmony_ci if (pbuf_remove_header(p, next_hdr_offset)) { 2533d8536b4Sopenharmony_ci return; 2543d8536b4Sopenharmony_ci } else { 2553d8536b4Sopenharmony_ci /* pass p to ARP module */ 2563d8536b4Sopenharmony_ci LogPrintln("recv arp packet"); 2573d8536b4Sopenharmony_ci ArpPackageProc(netif, p); 2583d8536b4Sopenharmony_ci } 2593d8536b4Sopenharmony_ci break; 2603d8536b4Sopenharmony_ci#endif /* LWIP_IPV4 && LWIP_ARP */ 2613d8536b4Sopenharmony_ci 2623d8536b4Sopenharmony_ci default: 2633d8536b4Sopenharmony_ci LogPrintln("type is other %d", type); 2643d8536b4Sopenharmony_ci break; 2653d8536b4Sopenharmony_ci } 2663d8536b4Sopenharmony_ci} 2673d8536b4Sopenharmony_ci 2683d8536b4Sopenharmony_cistatic void BtProxySend(struct netif *netif, struct pbuf *p) 2693d8536b4Sopenharmony_ci{ 2703d8536b4Sopenharmony_ci if (netif == NULL || p == NULL) { 2713d8536b4Sopenharmony_ci LogPrintln("%s : netif = NUll or p = NULL!", __func__); 2723d8536b4Sopenharmony_ci return; 2733d8536b4Sopenharmony_ci } 2743d8536b4Sopenharmony_ci#if ETH_PAD_SIZE 2753d8536b4Sopenharmony_ci (void)pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ 2763d8536b4Sopenharmony_ci#endif 2773d8536b4Sopenharmony_ci ParsePackageEthernet(netif, p); 2783d8536b4Sopenharmony_ci} 2793d8536b4Sopenharmony_ci 2803d8536b4Sopenharmony_cistatic struct netif *CreateBtNetIf() 2813d8536b4Sopenharmony_ci{ 2823d8536b4Sopenharmony_ci struct netif *btNetif = NULL; 2833d8536b4Sopenharmony_ci btNetif = (struct netif *)malloc(sizeof(struct netif)); 2843d8536b4Sopenharmony_ci if (btNetif == NULL) { 2853d8536b4Sopenharmony_ci LogPrintln("%s fail : netif malloc fail!", __func__); 2863d8536b4Sopenharmony_ci LWIP_ASSERT("btNetif malloc fail.", 0); 2873d8536b4Sopenharmony_ci return NULL; 2883d8536b4Sopenharmony_ci } 2893d8536b4Sopenharmony_ci (void)memset_s(btNetif, sizeof(struct netif), 0, sizeof(struct netif)); 2903d8536b4Sopenharmony_ci btNetif->drv_send = BtProxySend; 2913d8536b4Sopenharmony_ci btNetif->link_layer_type = BT_PROXY_IF; 2923d8536b4Sopenharmony_ci btNetif->hwaddr_len = ETH_HWADDR_LEN; 2933d8536b4Sopenharmony_ci (void)memcpy_s(&btNetif->hwaddr, sizeof(btNetif->hwaddr), NETIF_MAC, ETH_HWADDR_LEN); 2943d8536b4Sopenharmony_ci (void)memcpy_s(&btNetif->full_name, sizeof(btNetif->full_name), NETIF_NAME_BT, sizeof(NETIF_NAME_BT)); 2953d8536b4Sopenharmony_ci ip4_addr_t gw, ipaddr, netmask; 2963d8536b4Sopenharmony_ci IP4_ADDR(&gw, 192, 168, 167, 239); 2973d8536b4Sopenharmony_ci IP4_ADDR(&ipaddr, 192, 168, 167, 1); 2983d8536b4Sopenharmony_ci IP4_ADDR(&netmask, 255, 255, 255, 255); 2993d8536b4Sopenharmony_ci int ret = 0; 3003d8536b4Sopenharmony_ci if ((ret = netifapi_netif_add(btNetif, &ipaddr, &netmask, &gw, btNetif, driverif_init, tcpip_input)) != ERR_OK) { 3013d8536b4Sopenharmony_ci LogPrintln("%s : netifapi_netif_add fail!,ret=%d", __func__, ret); 3023d8536b4Sopenharmony_ci LWIP_ASSERT("btNetif add fail.", 0); 3033d8536b4Sopenharmony_ci return NULL; 3043d8536b4Sopenharmony_ci } 3053d8536b4Sopenharmony_ci LogPrintln("netifapi_netif_add success!"); 3063d8536b4Sopenharmony_ci netif_set_link_up(btNetif); 3073d8536b4Sopenharmony_ci netifapi_netif_set_up(btNetif); 3083d8536b4Sopenharmony_ci return btNetif; 3093d8536b4Sopenharmony_ci} 3103d8536b4Sopenharmony_ci 3113d8536b4Sopenharmony_cistatic void UdpTestNetifTask(void *p) 3123d8536b4Sopenharmony_ci{ 3133d8536b4Sopenharmony_ci (void)p; 3143d8536b4Sopenharmony_ci LogPrintln("net_socket_test_011.c enter"); 3153d8536b4Sopenharmony_ci g_testCase = TEST_CASE; 3163d8536b4Sopenharmony_ci int sfd; 3173d8536b4Sopenharmony_ci struct sockaddr_in srvAddr = { 0 }; 3183d8536b4Sopenharmony_ci struct sockaddr_in clnAddr = { 0 }; 3193d8536b4Sopenharmony_ci socklen_t clnAddrLen = sizeof(clnAddr); 3203d8536b4Sopenharmony_ci struct ifreq nif; 3213d8536b4Sopenharmony_ci int ret; 3223d8536b4Sopenharmony_ci 3233d8536b4Sopenharmony_ci btProxyNf = CreateBtNetIf(); 3243d8536b4Sopenharmony_ci 3253d8536b4Sopenharmony_ci /* socket creation */ 3263d8536b4Sopenharmony_ci sfd = socket(AF_INET, SOCK_DGRAM, 0); 3273d8536b4Sopenharmony_ci LWIP_ASSERT("socket invalid param.", sfd != -1); 3283d8536b4Sopenharmony_ci 3293d8536b4Sopenharmony_ci srvAddr.sin_family = AF_INET; 3303d8536b4Sopenharmony_ci srvAddr.sin_addr.s_addr = inet_addr(STACK_IP_BT); 3313d8536b4Sopenharmony_ci srvAddr.sin_port = htons(STACK_PORT); 3323d8536b4Sopenharmony_ci ret = bind(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr)); 3333d8536b4Sopenharmony_ci LWIP_ASSERT("socket invalid param.", ret == 0); 3343d8536b4Sopenharmony_ci 3353d8536b4Sopenharmony_ci char *inface = NETIF_NAME_BT; 3363d8536b4Sopenharmony_ci (void)strcpy_s(nif.ifr_name, sizeof(nif.ifr_name), inface); 3373d8536b4Sopenharmony_ci if (setsockopt(sfd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&nif, sizeof(nif)) < 0) { 3383d8536b4Sopenharmony_ci LogPrintln("set intaface fail"); 3393d8536b4Sopenharmony_ci LWIP_ASSERT("set intaface fail.", 0); 3403d8536b4Sopenharmony_ci } 3413d8536b4Sopenharmony_ci 3423d8536b4Sopenharmony_ci /* send */ 3433d8536b4Sopenharmony_ci clnAddr.sin_family = AF_INET; 3443d8536b4Sopenharmony_ci clnAddr.sin_addr.s_addr = inet_addr(PEER_IP_BT); 3453d8536b4Sopenharmony_ci clnAddr.sin_port = htons(PEER_PORT); 3463d8536b4Sopenharmony_ci (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); 3473d8536b4Sopenharmony_ci (void)strcpy_s(g_buf, sizeof(g_buf), MSG); 3483d8536b4Sopenharmony_ci ret = sendto(sfd, g_buf, strlen(MSG), 0, (struct sockaddr*)&clnAddr, 3493d8536b4Sopenharmony_ci (socklen_t)sizeof(clnAddr)); 3503d8536b4Sopenharmony_ci LogPrintln("client send success: %d", sfd); 3513d8536b4Sopenharmony_ci LWIP_ASSERT("socket invalid param.", ret != -1); 3523d8536b4Sopenharmony_ci 3533d8536b4Sopenharmony_ci /* recv */ 3543d8536b4Sopenharmony_ci (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); 3553d8536b4Sopenharmony_ci ret = recvfrom(sfd, g_buf, sizeof(g_buf), 0, (struct sockaddr*)&clnAddr, 3563d8536b4Sopenharmony_ci &clnAddrLen); 3573d8536b4Sopenharmony_ci LWIP_ASSERT("socket invalid param.", ret == strlen(MSG)); 3583d8536b4Sopenharmony_ci LogPrintln("cli recv: %s", g_buf); 3593d8536b4Sopenharmony_ci 3603d8536b4Sopenharmony_ci /* close socket */ 3613d8536b4Sopenharmony_ci ret = closesocket(sfd); 3623d8536b4Sopenharmony_ci LWIP_ASSERT("socket invalid param.", ret != -1); 3633d8536b4Sopenharmony_ci return; 3643d8536b4Sopenharmony_ci} 3653d8536b4Sopenharmony_ci 3663d8536b4Sopenharmony_ciint UdpTestNetif() 3673d8536b4Sopenharmony_ci{ 3683d8536b4Sopenharmony_ci int ret = sys_thread_new("udp_test_netif", UdpTestNetifTask, NULL, 3693d8536b4Sopenharmony_ci STACK_TEST_SIZE, TCPIP_THREAD_PRIO); 3703d8536b4Sopenharmony_ci ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23); 3713d8536b4Sopenharmony_ci return ret; 3723d8536b4Sopenharmony_ci} 3733d8536b4Sopenharmony_ci 3743d8536b4Sopenharmony_cistatic void ArpPackageProc(struct netif *netif, struct pbuf *p) 3753d8536b4Sopenharmony_ci{ 3763d8536b4Sopenharmony_ci struct etharp_hdr *hdr; 3773d8536b4Sopenharmony_ci ip4_addr_t sipaddr, dipaddr; 3783d8536b4Sopenharmony_ci hdr = (struct etharp_hdr *)p->payload; 3793d8536b4Sopenharmony_ci 3803d8536b4Sopenharmony_ci if (hdr->opcode != PP_HTONS(ARP_REQUEST)) { 3813d8536b4Sopenharmony_ci LogPrintln("opcode %d is not arp request", hdr->opcode); 3823d8536b4Sopenharmony_ci return; 3833d8536b4Sopenharmony_ci } 3843d8536b4Sopenharmony_ci 3853d8536b4Sopenharmony_ci inet_pton(AF_INET, GATEWAY_IP_BT, &sipaddr); 3863d8536b4Sopenharmony_ci inet_pton(AF_INET, STACK_IP_BT, &dipaddr); 3873d8536b4Sopenharmony_ci if (memcmp(&hdr->dipaddr, &sipaddr, sizeof(ip4_addr_t)) != EOK) { 3883d8536b4Sopenharmony_ci LogPrintln("hdr->dipaddr %u is invalid", hdr->dipaddr); 3893d8536b4Sopenharmony_ci return; 3903d8536b4Sopenharmony_ci } 3913d8536b4Sopenharmony_ci 3923d8536b4Sopenharmony_ci ReplayArpTask(); 3933d8536b4Sopenharmony_ci} 3943d8536b4Sopenharmony_ci 3953d8536b4Sopenharmony_cistatic void ReplayArpEncodeEthernet(struct netif *netif, struct pbuf *p) 3963d8536b4Sopenharmony_ci{ 3973d8536b4Sopenharmony_ci int ret; 3983d8536b4Sopenharmony_ci ret = pbuf_add_header(p, SIZEOF_ETH_HDR); 3993d8536b4Sopenharmony_ci ICUNIT_ASSERT_EQUAL(ret, 0, 1); 4003d8536b4Sopenharmony_ci 4013d8536b4Sopenharmony_ci struct eth_hdr *ethhdr; 4023d8536b4Sopenharmony_ci ethhdr = (struct eth_hdr *)p->payload; 4033d8536b4Sopenharmony_ci ethhdr->type = lwip_htons(ETHTYPE_ARP); 4043d8536b4Sopenharmony_ci SMEMCPY(ðhdr->dest, NETIF_MAC, ETH_HWADDR_LEN); 4053d8536b4Sopenharmony_ci SMEMCPY(ðhdr->src, PEER_MAC, ETH_HWADDR_LEN); 4063d8536b4Sopenharmony_ci 4073d8536b4Sopenharmony_ci driverif_input(netif, p); 4083d8536b4Sopenharmony_ci} 4093d8536b4Sopenharmony_ci 4103d8536b4Sopenharmony_cistatic void ReplayArp(void *ptemp) 4113d8536b4Sopenharmony_ci{ 4123d8536b4Sopenharmony_ci struct etharp_hdr *hdr; 4133d8536b4Sopenharmony_ci ip4_addr_t sipaddr, dipaddr; 4143d8536b4Sopenharmony_ci 4153d8536b4Sopenharmony_ci (void)ptemp; 4163d8536b4Sopenharmony_ci LogPrintln("encode arp replay packet"); 4173d8536b4Sopenharmony_ci inet_pton(AF_INET, GATEWAY_IP_BT, &sipaddr); 4183d8536b4Sopenharmony_ci inet_pton(AF_INET, STACK_IP_BT, &dipaddr); 4193d8536b4Sopenharmony_ci struct pbuf *p = pbuf_alloc(PBUF_LINK, SIZEOF_ETHARP_HDR, PBUF_RAM); 4203d8536b4Sopenharmony_ci hdr = (struct etharp_hdr *)p->payload; 4213d8536b4Sopenharmony_ci hdr->opcode = PP_HTONS(ARP_REPLY); 4223d8536b4Sopenharmony_ci /* Write the ARP MAC-Addresses */ 4233d8536b4Sopenharmony_ci SMEMCPY(&hdr->shwaddr, PEER_MAC, ETH_HWADDR_LEN); 4243d8536b4Sopenharmony_ci SMEMCPY(&hdr->dhwaddr, NETIF_MAC, ETH_HWADDR_LEN); 4253d8536b4Sopenharmony_ci /* Copy struct ip4_addr_wordaligned to aligned ip4_addr, to support compilers without 4263d8536b4Sopenharmony_ci * structure packing. */ 4273d8536b4Sopenharmony_ci IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T(&hdr->sipaddr, &sipaddr); 4283d8536b4Sopenharmony_ci IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T(&hdr->dipaddr, &dipaddr); 4293d8536b4Sopenharmony_ci hdr->hwtype = PP_HTONS(LWIP_IANA_HWTYPE_ETHERNET); 4303d8536b4Sopenharmony_ci hdr->proto = PP_HTONS(ETHTYPE_IP); 4313d8536b4Sopenharmony_ci /* set hwlen and protolen */ 4323d8536b4Sopenharmony_ci hdr->hwlen = ETH_HWADDR_LEN; 4333d8536b4Sopenharmony_ci hdr->protolen = sizeof(ip4_addr_t); 4343d8536b4Sopenharmony_ci 4353d8536b4Sopenharmony_ci ReplayArpEncodeEthernet(btProxyNf, p); 4363d8536b4Sopenharmony_ci} 4373d8536b4Sopenharmony_ci 4383d8536b4Sopenharmony_cistatic void ReplayArpTask() 4393d8536b4Sopenharmony_ci{ 4403d8536b4Sopenharmony_ci int ret; 4413d8536b4Sopenharmony_ci ret = sys_thread_new("replay_arp", ReplayArp, NULL, 4423d8536b4Sopenharmony_ci STACK_TEST_SIZE, TCPIP_THREAD_PRIO); 4433d8536b4Sopenharmony_ci ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23); 4443d8536b4Sopenharmony_ci} 445