Esempio n. 1
0
/*
 * TCP code. For TCP, a socket is created and listens.
 * A callback occurs when the packet is received. The callback handles the different types of TCP events,
 * including the handshake protocol.
 * Based off the sample tcpecho app provided in the picotcp library.
 */
void cb_tcpecho(uint16_t ev, struct pico_socket *s)
{
    int r = 0;

    ZF_LOGD("tcpecho> wakeup ev=%u\n", ev);

    if (ev & PICO_SOCK_EV_RD) {
        char buf[100];
        r = pico_socket_read(s, buf, 100);
        pico_socket_write(s, buf, r); // Immediately echo back a response
    }

    if (ev & PICO_SOCK_EV_CONN) {
        uint32_t ka_val = 0;
        struct pico_socket *sock_peer;
        struct pico_ip4 orig = {0};
        uint16_t port = 0;
        char peer[30] = {0};
        int yes = 1;

        sock_peer = pico_socket_accept(s, &orig, &port);
        pico_ipv4_to_string(peer, orig.addr);
        ZF_LOGD("Connection established with %s:%d.\n", peer, short_be(port));
        pico_socket_setoption(sock_peer, PICO_TCP_NODELAY, &yes);
        /* Set keepalive options - from picoTCP documentation */
        ka_val = 5;
        pico_socket_setoption(sock_peer, PICO_SOCKET_OPT_KEEPCNT, &ka_val);
        ka_val = 30000;
        pico_socket_setoption(sock_peer, PICO_SOCKET_OPT_KEEPIDLE, &ka_val);
        ka_val = 5000;
        pico_socket_setoption(sock_peer, PICO_SOCKET_OPT_KEEPINTVL, &ka_val);
    }

    if (ev & PICO_SOCK_EV_FIN) {
        ZF_LOGD("Socket closed. Exit normally. \n");
    }

    if (ev & PICO_SOCK_EV_ERR) {
        ZF_LOGD("Socket error received: %s. Bailing out.\n", strerror(pico_err));
    }

    if (ev & PICO_SOCK_EV_CLOSE) {
        ZF_LOGD("Socket received close from peer.\n");
        pico_socket_shutdown(s, PICO_SHUT_WR);
    }

    if (ev & PICO_SOCK_EV_WR) {
        ZF_LOGD("TCP Write ack\n");
    }
}
Esempio n. 2
0
void start_tcpecho()
{
    uint16_t listen_port = short_be(8777);
    int ret = 0, yes = 1;
    struct pico_socket *s = NULL;
    struct pico_ip4 ip4 = {0};

    s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, &cb_tcpecho);

    if (!s) {
        ZF_LOGE("%s: error opening socket: %s\n", __FUNCTION__, strerror(pico_err));
    }

    pico_socket_setoption(s, PICO_TCP_NODELAY, &yes);

    ret = pico_socket_bind(s, &ip4, &listen_port);

    if (ret < 0) {
        ZF_LOGE("%s: error binding socket to port %u: %s\n", __FUNCTION__, short_be(listen_port), strerror(pico_err));
    }

    if (pico_socket_listen(s, 40) != 0) {
        ZF_LOGE("%s: error listening on port %u\n", __FUNCTION__, short_be(listen_port));
    }

    ZF_LOGD("Launching PicoTCP echo server\n");
}
Esempio n. 3
0
void app_tcpclient()
{
    char *daddr = NULL, *dport = NULL;
    uint16_t send_port = 0, listen_port = short_be(5555);
    int i = 0, ret = 0, yes = 1;
    struct pico_socket *s = NULL;
    struct pico_ip4 dst = {0};
    struct pico_ip4 inaddr = {0};

    ZF_LOGD("Connecting to: %s:%d\n", daddr, short_be(send_port));

    s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, &cb_tcpclient);

    if (!s) {
        ZF_LOGE("%s: error opening socket: %s\n", __FUNCTION__, strerror(pico_err));
    }

    pico_socket_setoption(s, PICO_TCP_NODELAY, &yes);

    ret = pico_socket_bind(s, &inaddr, &listen_port);

    if (ret < 0) {
        ZF_LOGE("%s: error binding socket to port %u: %s\n", __FUNCTION__, short_be(listen_port), strerror(pico_err));
    }

    // Set the destination address (string) above in the usual xxx.xxx.xxx.xxx ip4 way.
    pico_string_to_ipv4(daddr, &dst.addr);

    ret = pico_socket_connect(s, &dst, send_port);

    if (ret < 0) {
        ZF_LOGE("%s: error connecting to %s:%u: %s\n", __FUNCTION__, daddr, short_be(send_port), strerror(pico_err));
    }

    ZF_LOGD("TCP client connected\n");

}
Esempio n. 4
0
void app_mcastsend_ipv6(char *arg)
{
    char *maddr = NULL, *laddr = NULL, *lport = NULL, *sport = NULL;
    uint16_t sendto_port = 0;
    struct pico_ip6 inaddr_link = {
        0
    }, inaddr_mcast = {
        0
    };
    char *new_arg = NULL, *p = NULL, *nxt = arg;
    struct pico_ip_mreq mreq = ZERO_MREQ_IP6;

    /* start of parameter parsing */
    if (nxt) {
        nxt = cpy_arg(&laddr, nxt);
        if (laddr) {
            pico_string_to_ipv6(laddr, &inaddr_link.addr);
        } else {
            goto out;
        }
    } else {
        /* no arguments */
        goto out;
    }

    if (nxt) {
        nxt = cpy_arg(&maddr, nxt);
        if (maddr) {
            pico_string_to_ipv6(maddr, &inaddr_mcast.addr);
        } else {
            goto out;
        }
    } else {
        /* missing multicast address */
        goto out;
    }

    if (nxt) {
        nxt = cpy_arg(&sport, nxt);
        if (sport && atoi(sport)) {
            sendto_port = short_be(atoi(sport));
        } else {
            /* incorrect send_port */
            goto out;
        }
    } else {
        /* missing send_port */
        goto out;
    }

    if (nxt) {
        nxt = cpy_arg(&lport, nxt);
        if (lport && atoi(lport)) {
            /* unused at this moment */
            /* listen_port = short_be(atoi(lport)); */
        } else {
            /* incorrect listen_port */
            goto out;
        }
    } else {
        /* missing listen_port */
        goto out;
    }

    picoapp_dbg("\n%s: mcastsend started. Sending packets to %s:%u\n\n", __FUNCTION__, maddr, short_be(sendto_port));

    /* udpclient:dest_addr:sendto_port[:listen_port:datasize:loops:subloops] */
    new_arg = calloc(1, strlen(maddr) + 1 + strlen(sport) + 1 + strlen(lport) + strlen(",64,10,5,") + 1);
    p = strcat(new_arg, maddr);
    p = strcat(p + strlen(maddr), ",");
    p = strcat(p + 1, sport);
    p = strcat(p + strlen(sport), ",");
    p = strcat(p + 1, lport);
    p = strcat(p + strlen(lport), ",64,10,5,");

    /* DAD needs to verify the link address before we can continue */
    while(!pico_ipv6_link_get(&inaddr_link) ) {
        pico_stack_tick();
        usleep(2000);
    }
    app_udpclient(new_arg);
    
    memcpy(&mreq.mcast_group_addr,&inaddr_mcast, sizeof(struct pico_ip6));
    memcpy(&mreq.mcast_link_addr ,&inaddr_link, sizeof(struct pico_ip6));
    if(pico_socket_setoption(udpclient_pas->s, PICO_IP_ADD_MEMBERSHIP, &mreq) < 0) {
        picoapp_dbg("%s: socket_setoption PICO_IP_ADD_MEMBERSHIP failed: %s\n", __FUNCTION__, strerror(pico_err));
        exit(1);
    }

    return;

out:
    picoapp_dbg("mcastsend expects the following format: mcastsend:link_addr:mcast_addr:sendto_port:listen_port\n");
    exit(255);
}
Esempio n. 5
0
void app_mcastsend(char *arg)
{
    char *maddr = NULL, *laddr = NULL, *lport = NULL, *sport = NULL;
    uint16_t sendto_port = 0;
    struct pico_ip4 inaddr_link = {
        0
    }, inaddr_mcast = {
        0
    };
    char *new_arg = NULL, *p = NULL, *nxt = arg;
    struct pico_ip_mreq mreq = ZERO_MREQ;

    /* start of parameter parsing */
    if (nxt) {
        nxt = cpy_arg(&laddr, nxt);
        if (laddr) {
            pico_string_to_ipv4(laddr, &inaddr_link.addr);
        } else {
            goto out;
        }
    } else {
        /* no arguments */
        goto out;
    }

    if (nxt) {
        nxt = cpy_arg(&maddr, nxt);
        if (maddr) {
            pico_string_to_ipv4(maddr, &inaddr_mcast.addr);
        } else {
            goto out;
        }
    } else {
        /* missing multicast address */
        goto out;
    }

    if (nxt) {
        nxt = cpy_arg(&sport, nxt);
        if (sport && atoi(sport)) {
            sendto_port = short_be(atoi(sport));
        } else {
            /* incorrect send_port */
            goto out;
        }
    } else {
        /* missing send_port */
        goto out;
    }

    if (nxt) {
        nxt = cpy_arg(&lport, nxt);
        if (lport && atoi(lport)) {
            /* unused at this moment */
            /* listen_port = short_be(atoi(lport)); */
        } else {
            /* incorrect listen_port */
            goto out;
        }
    } else {
        /* missing listen_port */
        goto out;
    }

    picoapp_dbg("\n%s: mcastsend started. Sending packets to %08X:%u\n\n", __FUNCTION__, long_be(inaddr_mcast.addr), short_be(sendto_port));

    /* udpclient:dest_addr:sendto_port[:listen_port:datasize:loops:subloops] */
    new_arg = calloc(1, strlen(maddr) + 1 + strlen(sport) + 1 + strlen(lport) + strlen(":64:10:5:") + 1);
    p = strcat(new_arg, maddr);
    p = strcat(p + strlen(maddr), ":");
    p = strcat(p + 1, sport);
    p = strcat(p + strlen(sport), ":");
    p = strcat(p + 1, lport);
    p = strcat(p + strlen(lport), ":64:10:5:");

    app_udpclient(new_arg);

    mreq.mcast_group_addr = inaddr_mcast;
    mreq.mcast_link_addr = inaddr_link;
    if(pico_socket_setoption(udpclient_pas->s, PICO_IP_ADD_MEMBERSHIP, &mreq) < 0) {
        picoapp_dbg("%s: socket_setoption PICO_IP_ADD_MEMBERSHIP failed: %s\n", __FUNCTION__, strerror(pico_err));
        exit(1);
    }

    return;

out:
    picoapp_dbg("mcastsend expects the following format: mcastsend:link_addr:mcast_addr:sendto_port:listen_port\n");
    exit(255);
}
Esempio n. 6
0
void cb_tcpecho(uint16_t ev, struct pico_socket *s)
{
    int r = 0;

    picoapp_dbg("tcpecho> wakeup ev=%u\n", ev);

    if (ev & PICO_SOCK_EV_RD) {
        if (flag & PICO_SOCK_EV_CLOSE)
            printf("SOCKET> EV_RD, FIN RECEIVED\n");

        while (len < BSIZE) {
            r = pico_socket_read(s, recvbuf + len, BSIZE - len);
            if (r > 0) {
                len += r;
                flag &= ~(PICO_SOCK_EV_RD);
            } else {
                flag |= PICO_SOCK_EV_RD;
                break;
            }
        }
        if (flag & PICO_SOCK_EV_WR) {
            flag &= ~PICO_SOCK_EV_WR;
            send_tcpecho(s);
        }
    }

    if (ev & PICO_SOCK_EV_CONN) {
        uint32_t ka_val = 0;
        struct pico_socket *sock_a = {
            0
        };
        struct pico_ip4 orig = {
            0
        };
        uint16_t port = 0;
        char peer[30] = {
            0
        };
        int yes = 1;

        sock_a = pico_socket_accept(s, &orig, &port);
        pico_ipv4_to_string(peer, orig.addr);
        printf("Connection established with %s:%d.\n", peer, short_be(port));
        pico_socket_setoption(sock_a, PICO_TCP_NODELAY, &yes);
        /* Set keepalive options */
        ka_val = 5;
        pico_socket_setoption(sock_a, PICO_SOCKET_OPT_KEEPCNT, &ka_val);
        ka_val = 30000;
        pico_socket_setoption(sock_a, PICO_SOCKET_OPT_KEEPIDLE, &ka_val);
        ka_val = 5000;
        pico_socket_setoption(sock_a, PICO_SOCKET_OPT_KEEPINTVL, &ka_val);
    }

    if (ev & PICO_SOCK_EV_FIN) {
        printf("Socket closed. Exit normally. \n");
        if (!pico_timer_add(2000, deferred_exit, NULL)) {
            printf("Failed to start exit timer, exiting now\n");
            exit(1);
        }
    }

    if (ev & PICO_SOCK_EV_ERR) {
        printf("Socket error received: %s. Bailing out.\n", strerror(pico_err));
        exit(1);
    }

    if (ev & PICO_SOCK_EV_CLOSE) {
        printf("Socket received close from peer.\n");
        if (flag & PICO_SOCK_EV_RD) {
            pico_socket_shutdown(s, PICO_SHUT_WR);
            printf("SOCKET> Called shutdown write, ev = %d\n", ev);
        }
    }

    if (ev & PICO_SOCK_EV_WR) {
        r = send_tcpecho(s);
        if (r == 0)
            flag |= PICO_SOCK_EV_WR;
        else
            flag &= (~PICO_SOCK_EV_WR);
    }
}