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(&ethhdr->dest, NETIF_MAC, ETH_HWADDR_LEN);
703d8536b4Sopenharmony_ci    SMEMCPY(&ethhdr->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(&ethhdr->dest, NETIF_MAC, ETH_HWADDR_LEN);
4053d8536b4Sopenharmony_ci    SMEMCPY(&ethhdr->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