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); }
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); }
void app_mcastsend_ipv6(char *arg) { picoapp_dbg("ERROR: PICO_SUPPORT_MCAST disabled\n"); return; }
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); } }