Beispiel #1
0
void callback_dhcpclient(void*cli, int code)
{
    struct pico_ip4 gateway;
    char gw_txt_addr[30];
    if(code == PICO_DHCP_SUCCESS) {
        gateway = pico_dhcp_get_gateway(&dhcp_client_ptr);
        pico_ipv4_to_string(gw_txt_addr, gateway.addr);
    }

    printf("callback happened with code %d!\n", code);
}
Beispiel #2
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");
    }
}
Beispiel #3
0
static int pico_dns_client_user_callback(struct pico_dns_answer_suffix *asuffix, struct pico_dns_query *q)
{
    uint32_t ip = 0;
    char *str = NULL;
    char *rdata = (char *) asuffix + sizeof(struct pico_dns_answer_suffix);

    switch (q->qtype)
    {
    case PICO_DNS_TYPE_A:
        ip = long_from(rdata);
        str = PICO_ZALLOC(PICO_DNS_IPV4_ADDR_LEN);
        pico_ipv4_to_string(str, ip);
        break;
#ifdef PICO_SUPPORT_IPV6
    case PICO_DNS_TYPE_AAAA:
    {
        struct pico_ip6 ip6;
        memcpy(&ip6.addr, rdata, sizeof(struct pico_ip6));
        str = PICO_ZALLOC(PICO_DNS_IPV6_ADDR_LEN);
        pico_ipv6_to_string(str, ip6.addr);
        break;
    }
#endif
    case PICO_DNS_TYPE_PTR:
        pico_dns_client_answer_domain(rdata);
        str = PICO_ZALLOC((size_t)(asuffix->rdlength - PICO_DNS_LABEL_INITIAL));
        if (!str) {
            pico_err = PICO_ERR_ENOMEM;
            return -1;
        }

        memcpy(str, rdata + PICO_DNS_LABEL_INITIAL, short_be(asuffix->rdlength) - PICO_DNS_LABEL_INITIAL);
        break;

    default:
        dns_dbg("DNS ERROR: incorrect qtype (%u)\n", q->qtype);
        break;
    }

    if (q->retrans) {
        q->callback(str, q->arg);
        q->retrans = 0;
        PICO_FREE(str);
        pico_dns_client_del_query(q->id);
    }

    return 0;
}
Beispiel #4
0
void cb_ping(struct pico_icmp4_stats *s)
{
    char host[30];
    pico_ipv4_to_string(host, s->dst.addr);
    if (s->err == 0) {
        dbg("%lu bytes from %s: icmp_req=%lu ttl=64 time=%lu ms\n", s->size, host, s->seq, s->time);
        if (s->seq == NUM_PING) {
            ping_test_var++;
        }

        fail_if (s->seq > NUM_PING);
    } else {
        dbg("PING %lu to %s: Error %d\n", s->seq, host, s->err);
        exit(1);
    }
}
Beispiel #5
0
void handle_picoserver_notification(void)
{
    picoserver_event_t server_event = echo_control_event_poll();
    int ret = 0;
    int socket = 0;
    uint16_t events = 0;
    char ip_string[16] = {0};

    while (server_event.num_events_left > 0 || server_event.events) {
        socket = server_event.socket_fd;
        events = server_event.events;
        if (events & PICOSERVER_CONN) {
            if (socket != listener_socket) {
                picoserver_peer_t peer = echo_control_accept(socket);
                if (peer.result == -1) {
                    assert(!"Failed to accept a peer");
                }
                pico_ipv4_to_string(ip_string, peer.peer_addr);
                printf("%s: Connection established with %s on socket %d\n", get_instance_name(), ip_string, socket);
            }
        }
        if (events & PICOSERVER_READ) {
            printf("%s: Received a message on socket %d, going to echo to Listener\n", get_instance_name(), socket);
            ret = echo_recv_recv(socket, 4096, 0);
            strncpy(echo_send_buf, echo_recv_buf, ret);
            ret = echo_send_send(listener_socket, strlen(echo_send_buf), 0);
            memset(echo_recv_buf, 0, 4096);
            memset(echo_send_buf, 0, 4096);
        }
        if (events & PICOSERVER_CLOSE) {
            ret = echo_control_shutdown(socket, PICOSERVER_SHUT_RDWR);
            printf("%s: Connection closing on socket %d\n", get_instance_name(), socket);
        }
        if (events & PICOSERVER_FIN) {
            printf("%s: Connection closed on socket %d\n", get_instance_name(), socket);
        }
        if (events & PICOSERVER_ERR) {
            printf("%s: Error with socket %d, going to die\n", get_instance_name(), socket);
            assert(0);
        }
        server_event = echo_control_event_poll();
    }
}
Beispiel #6
0
void ping_callback_dhcpclient(struct pico_icmp4_stats *s)
{
    char host[30] = { };

    pico_ipv4_to_string(host, s->dst.addr);
    if (s->err == 0) {
        dbg("DHCP client: %lu bytes from %s: icmp_req=%lu ttl=64 time=%lu ms\n",
            s->size, host, s->seq, (long unsigned int)s->time);
        if (s->seq >= 3) {
            dbg("DHCP client: TEST SUCCESS!\n");
            if (--dhcpclient_devices <= 0)
                exit(0);
        }
    } else {
        dbg("DHCP client: ping %lu to %s error %d\n", s->seq, host, s->err);
        dbg("DHCP client: TEST FAILED!\n");
        exit(1);
    }
}
static void pico_dns_client_callback(uint16_t ev, struct pico_socket *s)
{
  char *q_qname, *q_suf, *a_hdr, *a_qname, *a_suf, *a_rdata;
  struct dns_message_hdr *hdr;
  struct dns_query_suffix query_suf;
  struct dns_answer_suffix answer_suf;
  struct pico_dns_key test, *key;
  char *answer;
  char dns_answer[PICO_DNS_MAX_RESPONSE_LEN] = {0};
  uint8_t valid_suffix = 0;
  uint16_t compression = 0;
  int i = 0, r = 0;

  if (ev & PICO_SOCK_EV_RD) {
    r = pico_socket_read(s, dns_answer, PICO_DNS_MAX_RESPONSE_LEN);
    pico_socket_close(s);
    if (r == PICO_DNS_MAX_RESPONSE_LEN || r < (int)sizeof(struct dns_message_hdr)) {
      dns_dbg("DNS ERROR: received incorrect number(%d) of bytes\n", r);
      return;
    }

    /* Check header validity */
    a_hdr = dns_answer;
    hdr = (struct dns_message_hdr *) a_hdr;
    pico_dns_client_hdr_ntoh(hdr);
    if (GET_FLAG_QR(hdr) != PICO_DNS_QR_RESPONSE || GET_FLAG_OPCODE(hdr) != PICO_DNS_OPCODE_QUERY 
        || GET_FLAG_TC(hdr) == PICO_DNS_TC_IS_TRUNCATED || GET_FLAG_RCODE(hdr) != PICO_DNS_RCODE_NO_ERROR) {
      dns_dbg("DNS ERROR: OPCODE %d | TC %d | RCODE %d\n", GET_FLAG_OPCODE(hdr), GET_FLAG_TC(hdr), GET_FLAG_RCODE(hdr));
      return;
    }

    if (hdr->ancount < 1 || r < (int)(sizeof(struct dns_message_hdr) + hdr->qdcount * sizeof(struct dns_query_suffix)
            + hdr->ancount * sizeof(struct dns_answer_suffix))) {
      dns_dbg("DNS ERROR: ancount < 1 OR received number(%d) of bytes too low\n", r);
      return;
    }

    /* Find DNS key */
    test.id = hdr->id;

    key = pico_tree_findKey(&DNSTable,&test);
    if (!key) {
      dns_dbg("DNS WARNING: key with id %u not found\n", hdr->id);
      return;
    }
    key->retrans = 0;

    /* Check query suffix validity */
    q_qname = a_hdr + sizeof(struct dns_message_hdr);
    q_suf = pico_dns_client_seek(q_qname);
    query_suf = *(struct dns_query_suffix *) q_suf;
    if (short_be(query_suf.qtype) != key->qtype || short_be(query_suf.qclass) != key->qclass) {
      dns_dbg("DNS ERROR: received qtype (%u) or qclass (%u) incorrect\n", short_be(query_suf.qtype), short_be(query_suf.qclass));
      return;
    }

    /* Seek answer suffix */
    a_qname = q_suf + sizeof(struct dns_query_suffix);
    a_suf = a_qname;
    while(i++ < hdr->ancount) {
      uint16_t comp_h = short_from(a_suf);
      compression = short_be(comp_h);
      switch (compression >> 14)
      {
        case PICO_DNS_POINTER:
          while (compression >> 14 == PICO_DNS_POINTER) {
            dns_dbg("DNS: pointer\n");
            a_suf += sizeof(uint16_t);
            comp_h = short_from(a_suf);
            compression = short_be(comp_h);
          }
          break;

        case PICO_DNS_LABEL:
          dns_dbg("DNS: label\n");
          a_suf = pico_dns_client_seek(a_qname);
          break;

        default:
          dns_dbg("DNS ERROR: incorrect compression (%u) value\n", compression);
          return;
      }

      /* Check answer suffix validity */
      answer_suf = *(struct dns_answer_suffix *)a_suf;
      if (short_be(answer_suf.qtype) != key->qtype || short_be(answer_suf.qclass) != key->qclass) {
        dns_dbg("DNS WARNING: received qtype (%u) or qclass (%u) incorrect\n", short_be(answer_suf.qtype), short_be(answer_suf.qclass));
        a_suf = a_suf + sizeof(struct dns_answer_suffix) + short_be(answer_suf.rdlength);
        continue;
      }

      if (short_be(answer_suf.ttl) > PICO_DNS_MAX_TTL) {
        dns_dbg("DNS WARNING: received TTL (%u) > MAX (%u)\n", short_be(answer_suf.ttl), PICO_DNS_MAX_TTL);
        a_suf = a_suf + sizeof(struct dns_answer_suffix) + short_be(answer_suf.rdlength);
        continue;
      }

      valid_suffix = 1;
      break;
    }

    if (!valid_suffix) {
       dns_dbg("DNS ERROR: invalid dns answer suffix\n");
       return;
    }

    a_rdata = a_suf + sizeof(struct dns_answer_suffix);
    if (key->qtype == PICO_DNS_TYPE_A) {
      uint32_t ip_h = long_from(a_rdata);
      dns_dbg("DNS: length %u | ip %08X\n", short_be(answer_suf.rdlength), long_be(ip_h));
      answer = pico_zalloc(16);
      pico_ipv4_to_string(answer, ip_h);
      key->callback(answer, key->arg);
    } else if (key->qtype == PICO_DNS_TYPE_PTR) {
      pico_dns_client_reverse_label((char *) a_rdata);
      dns_dbg("DNS: length %u | name %s\n", short_be(answer_suf.rdlength), (char *)a_rdata + 1);
      answer = pico_zalloc(answer_suf.rdlength - 1);
      memcpy(answer, (char *)a_rdata + 1, short_be(answer_suf.rdlength) - 1);
      key->callback(answer, key->arg);
    } else {
      dns_dbg("DNS ERROR: incorrect qtype (%u)\n", key->qtype);
      return;
    }
  }
void serverWakeup(uint16_t ev, uint16_t conn)
{
    char * body;
    uint32_t read = 0;

    if(ev & EV_HTTPS_CON)
    {
        printf("New connection received\n");
        pico_https_server_accept();

    }

    if(ev & EV_HTTPS_REQ) /* new header received */
    {
        char *resource;
        int method;
        printf("Header request received\n");
        resource = pico_https_getResource(conn);
        if(strcmp(resource, "/") == 0)
        {
            resource = "/stm32f4.html";
        }
        method = pico_https_getMethod(conn);
        if(strcmp(resource, "/board_info") == 0)
        {

            pico_https_respond(conn, HTTPS_RESOURCE_FOUND);
            strcpy(http_buffer, "{\"uptime\":");
            pico_itoa(PICO_TIME(), http_buffer + strlen(http_buffer));
			
            strcat(http_buffer, ", \"l1\":\"");
            strcat(http_buffer, "on");

            strcat(http_buffer, "\", \"l2\":\"");
            strcat(http_buffer, "off");

            strcat(http_buffer, "\", \"l3\":\"");
            strcat(http_buffer, "on");
            
			strcat(http_buffer, "\", \"l4\":\"");
            strcat(http_buffer, "on");
			
			strcat(http_buffer, "\", \"button\":\"");
			strcat(http_buffer,  "up");
			
			strcat(http_buffer, "\"}");

            pico_https_submitData(conn, http_buffer, strlen(http_buffer));
        }
   

        else if(strcmp(resource, "/ip") == 0)
        {
            pico_https_respond(conn, HTTPS_RESOURCE_FOUND);

            struct pico_ipv4_link * link;
            link = pico_ipv4_link_by_dev(pico_dev_eth);
            if (link)
                pico_ipv4_to_string(http_buffer, link->address.addr);
            else
                strcpy(http_buffer, "0.0.0.0");
            pico_https_submitData(conn, http_buffer, strlen(http_buffer));
        }
		else if(strcmp(resource,"/led1") == 0){ pico_https_respond(conn, HTTPS_RESOURCE_FOUND); pico_https_submitData(conn, toggledString, sizeof(toggledString)); }
		else if(strcmp(resource,"/led2") == 0){ pico_https_respond(conn, HTTPS_RESOURCE_FOUND); pico_https_submitData(conn, toggledString, sizeof(toggledString)); }
		else if(strcmp(resource,"/led3") == 0){ pico_https_respond(conn, HTTPS_RESOURCE_FOUND); pico_https_submitData(conn, toggledString, sizeof(toggledString)); }
		else if(strcmp(resource,"/led4") == 0){ pico_https_respond(conn, HTTPS_RESOURCE_FOUND); pico_https_submitData(conn, toggledString, sizeof(toggledString)); }
        else /* search in flash resources */
        {
            struct Www_file * www_file;
            www_file = find_www_file(resource + 1);
            if(www_file != NULL)
            {
                uint16_t flags;
                flags = HTTPS_RESOURCE_FOUND | HTTPS_STATIC_RESOURCE;
                if(www_file->cacheable)
                {
                    flags = flags | HTTPS_CACHEABLE_RESOURCE;
                }
                pico_https_respond(conn, flags);
                pico_https_submitData(conn, www_file->content, (int) *www_file->filesize);
            } else { /* not found */
                /* reject */
		printf("Rejected connection...\n");
                pico_https_respond(conn, HTTPS_RESOURCE_NOT_FOUND);
            }
        }

    }


    if(ev & EV_HTTPS_PROGRESS) /* submitted data was sent */
    {
        uint16_t sent, total;
        pico_https_getProgress(conn, &sent, &total);
        printf("Chunk statistics : %d/%d sent\n", sent, total);
    }

    if(ev & EV_HTTPS_SENT) /* submitted data was fully sent */
    {
        printf("Last chunk post !\n");
        pico_https_submitData(conn, NULL, 0); /* send the final chunk */
    }

    if(ev & EV_HTTPS_CLOSE)
    {
        printf("Close request: %p\n", conn);
        if (conn)
            pico_https_close(conn);
        else
            printf(">>>>>>>> Close request w/ conn=NULL!!\n");
    }

    if(ev & EV_HTTPS_ERROR)
    {
        printf("Error on server: %p\n", conn);
        //TODO: what to do?
        //pico_http_close(conn);
    }
}
Beispiel #9
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);
    }
}