Ejemplo n.º 1
0
static int cmd_socket(int argc, char *argv[])
{
    if (cmd_parameter_index(argc, argv, "new") == 1) {
        return cmd_socket_new(argc, argv);
    } else if (cmd_parameter_index(argc, argv, "print-mode") > 0) {
        if (cmd_parameter_index(argc, argv, "--string") > 0) {
            printing_mode = PRINT_STRING;
        } else if (cmd_parameter_index(argc, argv, "--hex") > 0) {
            printing_mode = PRINT_HEX;
        } else if (cmd_parameter_index(argc, argv, "--disabled") > 0) {
            printing_mode = PRINT_DISABLED;
        }
        int32_t parsed_col_width = 0;
        if (cmd_parameter_int(argc, argv, "--col-width", &parsed_col_width)) {
            if (parsed_col_width <= 0) {
                cmd_printf("Printing column width must be > 0");
                return CMDLINE_RETCODE_FAIL;
            }
            if (printing_mode == PRINT_HEX && parsed_col_width > 42) {
                cmd_printf("Maximum column width for hex data is 42 bytes");
                return CMDLINE_RETCODE_FAIL;
            }
            printing_col_width = (int)parsed_col_width;
        }
        // Allow print-mode to be used as a parameter to other commands
        if (cmd_parameter_index(argc, argv, "print-mode") == 1) {
            return CMDLINE_RETCODE_SUCCESS;
        }
    }

    // Rest of the commands require Socket
    SInfo *info = get_sinfo(strtol(argv[1], NULL, 10));
    if (!info) {
        cmd_printf("Invalid socket id %s\r\n", argv[1]);
        return CMDLINE_RETCODE_FAIL;
    }

    bool enable_pattern_check;
    if (cmd_parameter_bool(argc, argv, "set_RFC_864_pattern_check", &enable_pattern_check)) {
        info->set_pattern_check(enable_pattern_check);
        return CMDLINE_RETCODE_SUCCESS;
    }

    // Helper macro for checking the which command was given
#define COMMAND_IS(cmd) (cmd_parameter_index(argc, argv, cmd) == 2)

    /*
     * Generic Socket commands:
     * delete, open, close, bind, set_blocking, set_timeout
     */

    if (COMMAND_IS("delete")) {
        return del_sinfo(info);

    } else if (COMMAND_IS("open")) {
        NetworkInterface *interface;

        interface = get_interface(); // get default interface

        if (!interface) {
            cmd_printf("Invalid interface\r\n");
            return CMDLINE_RETCODE_FAIL;
        }

        switch (info->type()) {
            case SInfo::IP:
                return handle_nsapi_error("Socket::open()", info->internetsocket()->open(interface));
            case SInfo::TCP_SERVER:
                return handle_nsapi_error("TCPServer::open()", info->tcp_server()->open(interface));
#if defined(MBEDTLS_SSL_CLI_C)
            case SInfo::TLS:
                return handle_nsapi_error("Socket::open()", info->tls_socket()->open(interface));
#endif
            default:
                cmd_printf("Not a IP socket\r\n");
                return CMDLINE_RETCODE_FAIL;
        }
    } else if (COMMAND_IS("close")) {
        return handle_nsapi_error("Socket::close()", info->socket().close());

    } else if (COMMAND_IS("bind")) {
        int32_t port = 0;
        char *addr;

        if (!cmd_parameter_int(argc, argv, "port", &port) && !cmd_parameter_int(argc, argv, "bind", &port) && port <= 0 && port > 65535) {
            printf("Missing or invalid port number\n");
            return CMDLINE_RETCODE_INVALID_PARAMETERS;
        }

        if (cmd_parameter_val(argc, argv, "addr", &addr)) {
            // Replace NULL-strings with NULL
            addr = strcmp(addr, "NULL") ? addr : NULL;
            cmd_printf("Socket::bind(%s, %" PRId32 ")\r\n", addr, port);
            SocketAddress tmp(addr, port);
            return handle_nsapi_error("Socket::bind(addr, port)", info->socket().bind(tmp));
        } else {
            cmd_printf("Socket::bind(%" PRId32 ")\r\n", port);
            SocketAddress tmp(NULL, port);
            return handle_nsapi_error("Socket::bind(port)", info->socket().bind(tmp));
        }

    } else if (COMMAND_IS("set_blocking")) {
        bool val;
        if (!cmd_parameter_bool(argc, argv, "set_blocking", &val)) {
            cmd_printf("Need boolean value");
            return CMDLINE_RETCODE_INVALID_PARAMETERS;
        }
        info->set_blocking(val);
        return CMDLINE_RETCODE_SUCCESS;

    } else if (COMMAND_IS("set_timeout")) {
        int32_t ms;
        if (!cmd_parameter_int(argc, argv, "set_timeout", &ms)) {
            cmd_printf("Need timeout value");
            return CMDLINE_RETCODE_INVALID_PARAMETERS;
        }
        if (ms == -1) {
            info->set_blocking(true);
        } else {
            info->set_blocking(false);
        }

        info->socket().set_timeout(ms);
        return CMDLINE_RETCODE_SUCCESS;

    } else if (COMMAND_IS("register_sigio_cb")) {
        info->socket().sigio(callback(sigio_handler, info));
        return CMDLINE_RETCODE_SUCCESS;
    }


    /*
     * Commands related to UDPSocket:
     * sendto, recvfrom
     */
    if (COMMAND_IS("sendto")) {
        return udp_sendto_command_handler(info, argc, argv);
    } else if (COMMAND_IS("recvfrom")) {
        return udp_recvfrom_command_handler(info, argc, argv);
    } else if (COMMAND_IS("start_udp_receiver_thread")) {
        return start_udp_receiver_thread(info, argc, argv);
    } else if (COMMAND_IS("last_data_received")) {
        print_data((const uint8_t *)info->getReceiveBuffer(), info->getDataCount());
        if (info->getPacketSizeArray()) {
            int *packetSizes = info->getPacketSizeArray();
            cmd_printf("packet_sizes: ");
            for (int i = 0; i < PACKET_SIZE_ARRAY_LEN; i++) {
                cmd_printf("%d ", packetSizes[i]);
            }
            cmd_printf("\r\n");
        }
        if (info->getReceiverThread()) {
            info->getReceiverThread()->terminate();
        }
        thread_clean_up(info);

        return handle_nsapi_error("Socket::last_data_received()", NSAPI_ERROR_OK);
    }

    /*
     * Commands related to TCPSocket, TLSSocket
     * connect, send, recv
     */
    if (COMMAND_IS("connect")) {
        char *host;
        int32_t port;

        if (!cmd_parameter_val(argc, argv, "connect", &host)) {
            cmd_printf("Need host name\r\n");
            return CMDLINE_RETCODE_INVALID_PARAMETERS;
        }
        if (!cmd_parameter_int(argc, argv, host, &port)) {
            cmd_printf("Need port number\r\n");
            return CMDLINE_RETCODE_INVALID_PARAMETERS;
        }
        if (strcmp(host, "NULL") == 0) {
            host = NULL;
        }

        cmd_printf("Host name: %s port: %" PRId32 "\r\n", host, port);
        if (info->type() == SInfo::IP) {
            SocketAddress addr(NULL, port);
            nsapi_error_t ret = get_interface()->gethostbyname(host, &addr);
            if (ret) {
                return handle_nsapi_error("NetworkInterface::gethostbyname()", ret);
            }
            return handle_nsapi_error("Socket::connect()", info->socket().connect(addr));
#if defined(MBEDTLS_SSL_CLI_C)
        } else if (info->type() == SInfo::TLS) {
            return handle_nsapi_error("TLSSocket::connect()", static_cast<TLSSocket &>(info->socket()).connect(host, port));
#endif
        }

    } else if (COMMAND_IS("send")) {
        return tcp_send_command_handler(info, argc, argv);

    } else if (COMMAND_IS("recv")) {
        return tcp_recv_command_handler(info, argc, argv);

    } else if (COMMAND_IS("start_tcp_receiver_thread")) {
        return start_tcp_receiver_thread(info, argc, argv);

    } else if (COMMAND_IS("join_tcp_receiver_thread")) {
        info->getReceiverThread()->join();
        print_data((const uint8_t *)info->getReceiveBuffer(), info->getDataCount());
        cmd_printf("received: %d bytes\r\n", info->getRecvTotal());

        thread_clean_up(info);

        return CMDLINE_RETCODE_SUCCESS;

    } else if (COMMAND_IS("start_bg_traffic_thread")) {
        return start_bg_traffic_thread(info, argc, argv);

    } else if (COMMAND_IS("join_bg_traffic_thread")) {
        int bg_thread_success = CMDLINE_RETCODE_SUCCESS;

        if (!info->available()) { // Tells that background thread stumbled to an issue and stopped prematurely
            bg_thread_success = CMDLINE_RETCODE_FAIL;
        }

        info->setUnavailable();
        info->getReceiverThread()->join();
        thread_clean_up(info);

        return bg_thread_success;
    } else if (COMMAND_IS("setsockopt_keepalive")) {
        int32_t seconds;
        nsapi_error_t ret;
        if (!cmd_parameter_int(argc, argv, "setsockopt_keepalive", &seconds)) {
            cmd_printf("Need keep-alive value(0-7200seconds)");
            return CMDLINE_RETCODE_INVALID_PARAMETERS;
        }

        ret = info->socket().setsockopt(NSAPI_SOCKET, NSAPI_KEEPALIVE, &seconds, sizeof(seconds));

        return handle_nsapi_error("Socket::setsockopt()", ret);
    }  else if (COMMAND_IS("getsockopt_keepalive")) {
        int32_t optval;
        unsigned optlen = sizeof(optval);
        nsapi_error_t ret;

        ret = info->socket().getsockopt(NSAPI_SOCKET, NSAPI_KEEPALIVE, &optval, &optlen);

        if (optlen != sizeof(int)) {
            return CMDLINE_RETCODE_FAIL;
        }
        if (ret < 0) {
            return handle_nsapi_error("Socket::getsockopt()", ret);
        }
        return handle_nsapi_size_or_error("Socket::getsockopt()", optval);
    }

    /*
     * Commands for TCPServer
     * listen, accept
     */
    if (COMMAND_IS("listen")) {
        int32_t backlog;
        if (cmd_parameter_int(argc, argv, "listen", &backlog)) {
            return handle_nsapi_error("TCPServer::listen()", info->socket().listen(backlog));
        } else {
            return handle_nsapi_error("TCPServer::listen()", info->socket().listen());
        }

    } else if (COMMAND_IS("accept")) {
        nsapi_error_t ret;

        if (info->type() != SInfo::TCP_SERVER) {
            Socket *new_sock = info->socket().accept(&ret);
            if (ret == NSAPI_ERROR_OK) {
                SInfo *new_info = new SInfo(new_sock, false);
                m_sockets.push_back(new_info);
                cmd_printf("Socket::accept() new socket sid: %d\r\n", new_info->id());
            }
            return handle_nsapi_error("Socket::accept()", ret);
        } else { // Old TCPServer API
            int32_t id;
            SocketAddress addr;

            if (!cmd_parameter_int(argc, argv, "accept", &id)) {
                cmd_printf("Need new socket id\r\n");
                return CMDLINE_RETCODE_INVALID_PARAMETERS;
            }
            SInfo *new_info = get_sinfo(id);
            if (!new_info) {
                cmd_printf("Invalid socket id\r\n");
                return CMDLINE_RETCODE_FAIL;
            }
            TCPSocket *new_sock = static_cast<TCPSocket *>(&new_info->socket());
            nsapi_error_t ret = static_cast<TCPServer &>(info->socket()).accept(new_sock, &addr);
            if (ret == NSAPI_ERROR_OK) {
                cmd_printf("TCPServer::accept() new socket sid: %d connection from %s port %d\r\n",
                           new_info->id(), addr.get_ip_address(), addr.get_port());
            }
            return handle_nsapi_error("TCPServer::accept()", ret);
        }
    }


    /*
     * Commands for TLSSocket
     * set_root_ca_cert
     */
#if defined(MBEDTLS_SSL_CLI_C)
    if (COMMAND_IS("set_root_ca_cert")) {
        if (info->type() != SInfo::TLS) {
            cmd_printf("Not a TLS socket.\r\n");
            return CMDLINE_RETCODE_FAIL;
        }
        return handle_nsapi_error("TLSSocket::tls_set_cert", tls_set_cert(argc, argv, info));
    }
#endif

    return CMDLINE_RETCODE_INVALID_PARAMETERS;
}
Ejemplo n.º 2
0
int process_requests(int s){
   char buffer[10000];
   fra_t fragment;
   struct sockaddr remote;
   int rlen,retval;
   int N=0;
   struct file_s file[100];
   
   struct fgetinfo p1;
   struct fgetfrag p2;
   struct finfo    *p4;
   struct ffrag    *p5;
  
   while (1) {
      switch (server_receive(s,buffer,sizeof(buffer),&remote,&rlen)){
         case 1:
            memcpy(&p1,buffer,sizeof(p1));
            if(check_fgetinfo(p1)){
               printf("Corrupted packet\n");
            }
            else{
               print_fgetinfo(p1);
               //check if file exists and can be open
               if((file[N].fd=(FILE *)fopen(p1.file_path,"r"))==NULL){
                  // If file not found tell the client
                  p4=get_sinfo(0,0,0);
               }
               else{
                  strncpy(file[N].file_path,p1.file_path,FILENAME_MAX);
                  file[N].file_id=N;
                  // If file found, tell the client info about it
                  fseek(file[N].fd, 0, SEEK_END);      // seek to end of file
                  file[N].size=ftell(file[N].fd); // get file size
                  // Has no sense to seek back to beginning of file
                  p4=get_sinfo(1,file[N].file_id,file[N].size);
                  N++;
               }
               // Send info about the file
               if(reply(s,&remote,rlen,p4,sizeof(*p4))){
                  printf("Error sending\n");
               }
            }
            break;
         case 2:
            memcpy(&p2,buffer,sizeof(p2));
            if(check_fgetfrag(p2)){
               printf("Corrupted packet\n");
            }
            else{
               // Send fragment
               fseek(file[p2.file_id].fd,SEEK_SET,p2.offset);
               if((retval=fread(fragment,sizeof(char),sizeof(fra_t),file[p2.file_id].fd))<=0){
                  printf("Nothing read\n");
               }
               p5=get_ffrag(p2.file_id,p2.offset,fragment,retval);
               if(reply(s,&remote,rlen,p5,sizeof(*p5))){
                  printf("Error sending\n");
               }
            }
            break;
         case 0:
            printf("Error receiving\n");
            break;
         default:
            printf("Unknown packet received\n");
            break;
      }   
   }
}