Beispiel #1
0
// Loop for communication with last sensor
void last_loop()
{
    print_info("Last loop");
    while(1)
    {
        if(mode == RECONF)
        {
            sleep(1);
            continue;
        }
        print_info("Waiting for data from last...");
        unsigned char buf[MAX_DATA];
        unsigned last_addr_len = sizeof(last_addr);
        int len = recvfrom(sock_last, buf, MAX_DATA, 0, (struct sockaddr*)&last_addr, &last_addr_len);
        if(len < 0)
        {
            mode = DOUBLE_LIST;
            resolving_error = 1;
            print_warning("Didn't receive data message from last sensor");
            print_success("Mode changed to double-list");
            if(send_error_msg(FIRST) < 0 || receive_ack_and_finit(FIRST) < 0)
            {
                close_first = 1;
            }
            if(send_error_msg(LAST) < 0 || receive_ack_and_finit(LAST) < 0)
            {
                resolving_error = 0;
                return;
            }
            resolving_error = 0;
        }
        else
        {
            union msg received_msg;
            int msg_type = unpack_msg(buf, &received_msg);
            switch(msg_type)
            {
            case INIT_MSG:
                take_init_msg(received_msg.init);
                break;
            case DATA_MSG:
                take_data_msg(received_msg.data);
                break;
            default:
                print_warning("Received unknown bytes");
            }
            cleanup_msg(&received_msg);
        }
        usleep(SERVER_TIMEOUT*1000);
        if(mode == DOUBLE_LIST)
        {
            print_info("Sending data to last sensor...");
            send_data_msg(LAST);
        }
    }
}
Beispiel #2
0
/** @brief Handles HTTP GET requests.
 *  Reads and parses the request, the uri, and dispatches the appropriate
 *  functions to serve content.
 *  @param conn_fd The connection file descriptor.
 *  @return none.
 */
void handle_request(int conn_fd)
{
	rio_t rio;
	char request[MAXLINE], uri[MAXLINE];
	char file_name[MAXLINE], cgi_args[MAXLINE];
	int is_static;
	struct stat st_buf;

	Rio_readinitb(&rio, conn_fd);

	/* Read first header line of incoming request. */
	if (rio_readlineb(&rio, request, MAXLINE) < 0) {
		dbg_printf("rio_readlineb error\n");
		return;
	}
	dbg_printf("Request: %s", request);

	if (parse_request_header(conn_fd, request, uri) != SUCCESS) {
		return;
	}

	if (read_request_headers(&rio) != SUCCESS) {
		return;
	}

	find_file(uri, file_name, cgi_args, &is_static);

	if (stat(file_name, &st_buf) < 0) {
		dbg_printf("404: File not found: %s\n", file_name);
		send_error_msg(conn_fd, "404", "File not found");
		return;
	}

	/* Handle static content */
	if (is_static) {
		if (!(S_ISREG(st_buf.st_mode)) || !(S_IRUSR & st_buf.st_mode)) {
			dbg_printf("403: Can't read the file: %s\n", file_name);
			send_error_msg(conn_fd, "403", "Can't read the file.");
			return;
		}
		serve_static(conn_fd, file_name, st_buf.st_size);
	}
	/* Handle dynamic content */
	else {
		if (!(S_ISREG(st_buf.st_mode)) || !(S_IXUSR & st_buf.st_mode)) {
			dbg_printf("403: Can't run the CGI program: %s\n", file_name);
			send_error_msg(conn_fd, "403", "Can't run the CGI program.");
	 		return;
		}
		serve_dynamic(conn_fd, file_name, cgi_args);
	}
}
Beispiel #3
0
int parse_request_header_bla(int conn_fd, char *request, char *uri)
{
	char method[MAXLINE], version[MAXLINE];

	/* Parse fields of incoming request. */
	if (sscanf(request, "%s %s %s", method, uri, version) != 3) {
		dbg_printf("Error occured during parsing request\n");
		return ERROR;
	}

	/* Only handles GET methods */
	if (strcasecmp(method, "GET") != 0) {
		dbg_printf("501: The method %s is not handled\n", method);
		send_error_msg(conn_fd, "501", "Not implemented.");
		return ERROR;
	}

	/* Only handles HTTP/1.0 versions */
	/* Not performing this check to be able to test with modern browsers. */
/*	if (strcasecmp(version, "HTTP/1.0") != 0) {
		printf("501: The version %s is not handled\n", version);
		return ERROR;
	}
*/
	return SUCCESS;
}
Beispiel #4
0
void run_networking() {
    int udp_sockfd;
    int udp_portno;
    int udp_clientlen;
    struct sockaddr_in udp_serveraddr;
    struct sockaddr_in udp_clientaddr;
    struct hostent *udp_hostp;
    char buf[BUFSIZE];
    char *udp_hostaddrp;
    int udp_optval;
    int n;
    
    udp_portno = atoi(param_udpport);
    
    udp_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    
    if(udp_sockfd < 0) {
        error("ERROR opening udp socket");
    }
    
    udp_optval = 1;
    setsockopt(udp_sockfd, SOL_SOCKET, SO_REUSEADDR,
               (const void *)&udp_optval, sizeof(int));
    
    bzero((char *) &udp_serveraddr, sizeof(udp_serveraddr));
    udp_serveraddr.sin_family = AF_INET;
    udp_serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    udp_serveraddr.sin_port = htons((unsigned short)udp_portno);
    
    if(bind(udp_sockfd, (struct sockaddr *)&udp_serveraddr, sizeof(udp_serveraddr)) < 0) {
        error("ERROR on udp binding");
    }
    
    udp_clientlen = sizeof(udp_clientaddr);
    
    // cleanup players list
    cleanup_players();
    
    int old_players_connected = 0;
    while(1) {
        bzero(buf, BUFSIZE);
        
        n = recvfrom(udp_sockfd, buf, BUFSIZE, 0, (struct sockaddr *)&udp_clientaddr, &udp_clientlen);
        
        if(n < 0) {
            error("ERROR in recvfrom");
        }
        
        old_players_connected = players_connected;
        for(int i = 0; i < MAX_PLAYERS; i++) {
            if(!players[i].free) {
                if(abs(players[i].ping - time(0)) > PING_TIMEOUT / 2) {
                    struct connect_four_packet_ping * packet_ping = malloc(sizeof(struct connect_four_packet_ping));
                    packet_ping->msg_code = MSG_PING;
                    
                    printf("PING %s %d\n", inet_ntoa(players[i].addr.sin_addr), ntohs(players[i].addr.sin_port));
                    
                    players[i].ping = time(0);
                    
                    printf("PING diff %lu %lu\n", players[i].ping, players[i].pong);
                    
                    if(abs(players[i].ping - players[i].pong) >= PING_TIMEOUT) {
                        players[i].free = 1;
                        players_connected--;
                        continue;
                    }
                    
                    n = sendto(udp_sockfd, packet_ping, sizeof(*packet_ping), 0, &players[i].addr, sizeof(players[i].addr));
                }
            }
        }
        
        if(old_players_connected > players_connected) {
            show_player_list();
        }
        
        struct connect_four_packet_common *recvpacket = buf;
        
        printf("Got packet with message code: %ld\n", recvpacket->msg_code);
        
        switch(recvpacket->msg_code) {
            case MSG_PONG:
                {
                    struct connect_four_packet_pong *packet_pong = recvpacket;
                    
                    for(int i = 0; i < MAX_PLAYERS; i++) {
                        if((players[i].addr.sin_addr.s_addr == udp_clientaddr.sin_addr.s_addr) &&
                           (players[i].addr.sin_port == udp_clientaddr.sin_port)) {
                            players[i].pong = time(0);
                        }
                    }
                }
                break;
            case MSG_JOIN:
                {
                    if(game != NULL) {
                        n = send_error_msg(udp_sockfd, "Game running. New clients are not allowed.", &udp_clientaddr, udp_clientlen, 1);
                        break;
                    }
                    
                    int free_slot_id = -1;
                    int player_exists = 0;
                    for(int i = 0; i < MAX_PLAYERS; i++) {
                        if(players[i].free) {
                            if(free_slot_id == -1) {
                                free_slot_id = i;
                            }
                        }
                        
                        if((players[i].addr.sin_addr.s_addr == udp_clientaddr.sin_addr.s_addr) &&
                           (players[i].addr.sin_port == udp_clientaddr.sin_port)) {
                            player_exists = 1;
                        }
                    }
                    
                    if(player_exists) {
                        n = send_error_msg(udp_sockfd, "You are already registered for a game.", &udp_clientaddr, udp_clientlen, 0);
                    } else if(free_slot_id == -1) {
                        n = send_error_msg(udp_sockfd, "Game full. New clients are not allowed.", &udp_clientaddr, udp_clientlen, 2);
                    } else {
                        players_connected++;
                        players[free_slot_id].addr.sin_family = AF_INET;
                        players[free_slot_id].addr.sin_addr.s_addr = udp_clientaddr.sin_addr.s_addr;
                        players[free_slot_id].addr.sin_port = udp_clientaddr.sin_port;
                        players[free_slot_id].free = 0;
                        players[free_slot_id].ready = 0;
                        
                        struct connect_four_packet_ok *packet_ok = malloc(sizeof(struct connect_four_packet_ok));
                        packet_ok->msg_code = MSG_OK;
                        packet_ok->player_count = players_connected;
                        packet_ok->player_id = players[free_slot_id].player_id;
                        
                        n = sendto(udp_sockfd, packet_ok, sizeof(*packet_ok), 0, (struct sockaddr *)&udp_clientaddr, udp_clientlen);
                        
                        free(packet_ok);
                    }
                    
                    show_player_list();
                }
                break;
            case MSG_READY:
                {
                    int ready_players = 0;
                    for(int i = 0; i < MAX_PLAYERS; i++) {
                        if(!players[i].free) {
                            if((players[i].addr.sin_addr.s_addr == udp_clientaddr.sin_addr.s_addr) &&
                               (players[i].addr.sin_port == udp_clientaddr.sin_port)) {
                                players[i].ready = 1;
                            }
                            
                            if(players[i].ready) {
                                ready_players++;
                            }
                        }
                    }
                    
                    printf("START ready_players %d players_connected %d", ready_players, players_connected);
                    if((ready_players >= 2) && (players_connected == ready_players)) {
                        /*
                         * Everyone's ready, let's start the game!
                         */
                        struct connect_four_packet_start *packet_start = malloc(sizeof(struct connect_four_packet_start));
                        packet_start->msg_code = MSG_START;
                        
                        switch(players_connected) {
                            case 2:
                                packet_start->column_count = 6;
                                packet_start->row_count = 7;
                                break;
                            case 3:
                            case 4:
                                packet_start->column_count = 7;
                                packet_start->row_count = 9;
                                break;
                        }
                        
                        game = newGame(packet_start->column_count, packet_start->row_count);
                        game->players = players_connected;
                        
                        packet_start->player_count = players_connected;
                        
                        
                        for(int i = 0; i < MAX_PLAYERS; i++) {
                            if(!players[i].free)
                                n = sendto(udp_sockfd, packet_start, sizeof(*packet_start), 0, &players[i].addr, sizeof(players[i].addr));
                        }
                        
                        free(packet_start);
                        
                        for(int i = 0; i < MAX_PLAYERS; i++) {
                            if(!players[i].free) {
                                if(players[i].player_id == (game->turn - '0')) {
                                    struct connect_four_packet_turn *packet_turn = malloc(sizeof(struct connect_four_packet_turn));
                                    
                                    packet_turn->msg_code = MSG_TURN;
                                    
                                    sendto(udp_sockfd, packet_turn, sizeof(*packet_turn), 0, &players[i].addr, sizeof(players[i].addr));
                                    
                                    free(packet_turn);
                                    break;
                                }
                            }
                        }
                    }
                    
                    show_player_list();
                }
                break;
            case MSG_COLUMN:
                {
                    if(game == NULL) {
                        n = send_error_msg(udp_sockfd, "Game's not started yet.", &udp_clientaddr, udp_clientlen, 3);
                        break;
                    }
                    
                    int valid_player = 0;
                    for(int i = 0; i < MAX_PLAYERS; i++) {
                        if(!players[i].free) {
                            if((players[i].addr.sin_addr.s_addr == udp_clientaddr.sin_addr.s_addr) &&
                               (players[i].addr.sin_port == udp_clientaddr.sin_port) &&
                               (players[i].player_id == (game->turn - '0'))) {
                                int old_moves = game->moves;
                                
                                struct connect_four_packet_column *packet_column = buf;
                                makeMove(game, packet_column->selected_column);
                                
                                char winner = hasWon(game, packet_column->selected_column);
                                
                                struct connect_four_packet_area *packet_area = malloc(sizeof(struct connect_four_packet_area));
                                packet_area->msg_code = MSG_AREA;
                                game->array[game->height * game->width] = 0;
                                strcpy(packet_area->area, game->array);
                                
                                printf("=======\n");
                                printf("Sending game data: %s", packet_area->area);
                                printf("=======\n");
                                
                                for(int i = 0; i < MAX_PLAYERS; i++) {
                                    if(!players[i].free)
                                        n = sendto(udp_sockfd, packet_area, sizeof(*packet_area), 0, &players[i].addr, sizeof(players[i].addr));
                                }
                                
                                free(packet_area);
                                
                                if((winner != 'f') || (game->moves == game->width * game->height)) {
                                    struct connect_four_packet_winner *packet_winner = malloc(sizeof(struct connect_four_packet_winner));
                                    
                                    packet_winner->msg_code = MSG_WINNER;
                                    if(winner == 'f') {
                                        packet_winner->winner_id = 0;
                                    } else {
                                        packet_winner->winner_id = winner - '0';
                                    }
                                    
                                    for(int i = 0; i < MAX_PLAYERS; i++) {
                                        if(!players[i].free)
                                            n = sendto(udp_sockfd, packet_winner, sizeof(*packet_winner), 0, &players[i].addr, sizeof(players[i].addr));
                                    }
                                    
                                    free(packet_winner);
                                    
                                    cleanup_players();
                                    
                                    free(game);
                                    game = NULL;
                                } else {
                                    for(int i = 0; i < MAX_PLAYERS; i++) {
                                        if(!players[i].free) {
                                            if(players[i].player_id == (game->turn - '0')) {
                                                struct connect_four_packet_turn *packet_turn = malloc(sizeof(struct connect_four_packet_turn));
                                                
                                                packet_turn->msg_code = MSG_TURN;
                                                
                                                sendto(udp_sockfd, packet_turn, sizeof(*packet_turn), 0, &players[i].addr, sizeof(players[i].addr));
                                                
                                                free(packet_turn);
                                                break;
                                            }
                                        }
                                    }
                                }
                                
                                if(game != NULL) {
                                    if(old_moves == game->moves) {
                                        n = send_error_msg(udp_sockfd, "Column full. Select another.", &udp_clientaddr, udp_clientlen, 4);
                                        break;
                                    }
                                }
                                
                                valid_player = 1;
                                break;
                            }
                        }
                    }
                    
                    if(!valid_player) {
                        n = send_error_msg(udp_sockfd, "It's not your turn!", &udp_clientaddr, udp_clientlen, 0);
                    }
                }
                break;
            case MSG_QUIT:
                for(int i = 0; i < MAX_PLAYERS; i++) {
                    printf("QUIT issued\n");
                    printf("%u\n = %u\n", players[i].addr.sin_addr.s_addr, udp_clientaddr.sin_addr.s_addr);
                    printf("%hu\n = %hu\n", players[i].addr.sin_port, udp_clientaddr.sin_port);
                    if((players[i].addr.sin_addr.s_addr == udp_clientaddr.sin_addr.s_addr) &&
                       (players[i].addr.sin_port == udp_clientaddr.sin_port)) {
                        bzero((char *)&players[i].addr, sizeof(players[i].addr));
                        players[i].free = 1;
                        players_connected--;
                    }
                }
                show_player_list();
                break;
            case MSG_CHAT_CLIENT:
                {
                    struct connect_four_packet_chat_client * packet_chat_client = recvpacket;
                    
                    struct connect_four_packet_chat_server * packet_chat_server = malloc(sizeof(struct connect_four_packet_chat_server));
                    packet_chat_server->msg_code = MSG_CHAT_SERVER;
                    
                    strcpy(packet_chat_server->msg, packet_chat_client->msg);
                    packet_chat_server->length = strlen(packet_chat_server->msg);
                    
                    for(int i = 0; i < MAX_PLAYERS; i++) {
                        if((players[i].addr.sin_addr.s_addr == udp_clientaddr.sin_addr.s_addr) &&
                           (players[i].addr.sin_port == udp_clientaddr.sin_port)) {
                            packet_chat_server->player_id = players[i].player_id;
                        }
                    }
                    
                    for(int i = 0; i < MAX_PLAYERS; i++) {
                        if(!players[i].free)
                            n = sendto(udp_sockfd, packet_chat_server, sizeof(*packet_chat_server), 0, &players[i].addr, sizeof(players[i].addr));
                    }
                    
                    
                    free(packet_chat_server);
                }
                break;
            case MSG_CHAT_SERVER:
                // implemented
            case MSG_AREA:
                // implemented
            case MSG_TURN:
                // implemented
            case MSG_START:
                // implemented
            case MSG_OK:
                // implemented
            case MSG_WINNER:
                // implemented
                n = send_error_msg(udp_sockfd, "Got server-answer command from client.", &udp_clientaddr, udp_clientlen, 0);
                break;
            default:
                if(n < 2) {
                    n = send_error_msg(udp_sockfd, "Unknown command received.", &udp_clientaddr, udp_clientlen, 0);
                } else {
                    udp_hostp = gethostbyaddr((const char*)&udp_clientaddr.sin_addr.s_addr, sizeof(udp_clientaddr.sin_addr.s_addr), AF_INET);
                    
                    if(udp_hostp == NULL) {
                        error("ERROR on gethostbyaddr");
                    }
                    
                    udp_hostaddrp = inet_ntoa(udp_clientaddr.sin_addr);
                    
                    if(udp_hostaddrp == NULL) {
                        error("ERROR on inet_ntoa");
                    }
                    
                    n = sendto(udp_sockfd, buf, strlen(buf), 0, (struct sockaddr *)&udp_clientaddr, udp_clientlen);
                }
                break;
        }
        
        if(n < 0) {
            error("ERROR in sendto");
        }
    }
}
Beispiel #5
0
int wpc_mgr_procservermsg() 
{
	int nbytes;
	int written;
	int write_len;
	int fd;
	u_int8_t buf[MAX_PAYLOAD]={'\0'};
	
	nbytes = wpc_recv(wpc_server_sock, buf, NSP_HDR_LEN, 0);
	struct nsp_header *nsp_header = (struct nsp_header *) buf;
	struct nsp_header nsp_hdr;
	int len = 0;
	//TBD: read length from frame header
	switch (nsp_header->frame_type)
	{
		case NSP_MRQST:
			len = MREQ_LEN;
			break;
		case NSP_SRQST:
			len = SREQ_LEN;
			break;
		case NSP_CRQST:
			len = CAPREQ_LEN;
			break;
		case NSP_WAKEUPRQST:
			len = WAKEUPREQ_LEN;
			break;
		case NSP_TSFRQST:
			len = TSFREQ_LEN;
			break;
		case NSP_STARETURNTOSLEEPREQ:
			len = SLEEPREQ_LEN;
			break;
		case NSP_WPCDBGRGST:
			len = WPCDBGREQ_LEN;
			break;
	}
	print_nsp_header(nsp_header);
	nbytes += wpc_recv(wpc_server_sock, buf+NSP_HDR_LEN, len, 0);
	if (nbytes <= 0) {
		//error or connection closed by client
		if (nbytes == 0)
			printf("selectserver: socket %d hung up\n", fdcount);
		else 
			printf("recv failed\n");
		wpc_close(wpc_server_sock);


        if(wpc_server_sock > 0)
    		FD_CLR(wpc_server_sock, &read_fds);

		wpc_server_sock = -1;
	} else {
		buf[nbytes] = '\0';

		struct nsp_mrqst *mrqst;
		struct nsp_sreq *srqst;
		struct nsp_cap_req *crqst;
		struct nsp_wakeup_req *wrqst;
		struct nsp_tsf_req *tsfrqst;
		struct nsp_sleep_req *slrqst;
		struct nsp_wpc_dbg_req *wpcdbgrqst;
		struct nsp_wpc_dbg_resp wpcdbgresp;
		struct request_no *reqno;
		struct timeval tv;
		time_t req_curtime;
		char time_buf[30];
		reqno = (struct request_no *)(((char *)buf) + NSP_HDR_LEN);

		if( nsp_header->version > NSP_VERSION ) {
			printf("ERROR: Request protocol version no (%02x) >  Current Version (%02x)\n",nsp_header->version, NSP_VERSION);
			send_error_msg(reqno->request_id, NSP_UNSUPPORTED_PROTOCOL_VERSION);
			return -1;
		}

		switch (nsp_header->frame_type)
		{
		case NSP_MRQST: 
			mrqst = (struct nsp_mrqst *)(((char *)buf) + NSP_HDR_LEN);
                request_id = mrqst->request_id;
                if (wpc_debug) {
                    if (wpc_dbg_log_len + WPCDBGHDR_LEN <= WPC_DBG_SIZE) {
                        dump_wpc_log(__LINE__, nsp_header->frame_type);
                    }
                    else {
                        printf("wpc log file is full:cannot written\n");
                        return;
                    }

                }
                else {
                    print_mrqst(mrqst);
                    gettimeofday(&tv, NULL);
                    req_curtime=tv.tv_sec;
                    strftime(time_buf,30,"%m-%d-%Y  %T.",localtime(&req_curtime));
                    PRIN_LOG("Req Time%s %ld\n",time_buf,tv.tv_usec);
                    if((mrqst->mode & NSP_MRQSTTYPE_MASK) ==  NSP_MRQSTTYPE_TYPE0) {
                        PRIN_LOG("%s: %d: Received a Type 0 Measurement Request\n", __FUNCTION__, __LINE__);
                        wpc_mgr_proctype0mreq(buf);
                    }else if((mrqst->mode & NSP_MRQSTTYPE_MASK) ==  NSP_MRQSTTYPE_TYPE1) {
                        PRIN_LOG("%s: %d: Received a Type 1 Measurement Request\n", __FUNCTION__, __LINE__);
                        wpc_mgr_proctype1mreq(buf);
                    }
                }
			break;
		case NSP_SRQST: 
			srqst = (struct nsp_sreq *)(((char *)buf) + NSP_HDR_LEN);
            if (wpc_debug) {
                if (wpc_dbg_log_len + WPCDBGHDR_LEN <= WPC_DBG_SIZE) {
                    dump_wpc_log(__LINE__, nsp_header->frame_type);
                }
                else {
                    printf("wpc log file is full:cannot written\n");
                    return;
                }
            }
            else {
                print_srqst(srqst);
            }
			break;
		case NSP_CRQST: 
			crqst = (struct nsp_cap_req *)(((char *)buf) + NSP_HDR_LEN);
            if (wpc_debug) {
                if (wpc_dbg_log_len + WPCDBGHDR_LEN <= WPC_DBG_SIZE) {
                    dump_wpc_log(__LINE__, nsp_header->frame_type);
                }
                else {
                    printf("wpc log file is full:cannot written\n");
                    return;
                }
            }
            else {
                print_crqst(crqst);
            }
			break;
		case NSP_WAKEUPRQST:
			wrqst = (struct nsp_wakeup_req *) (((char *)buf) + NSP_HDR_LEN);
            if (wpc_debug) {
                if (wpc_dbg_log_len + WPCDBGHDR_LEN <= WPC_DBG_SIZE) {
                    dump_wpc_log(__LINE__, nsp_header->frame_type);
                }
                else {
                    printf("wpc log file is full:cannot written\n");
                    return;
                }
            }
            else {
                print_wrqst(wrqst);
            }
			break;
		case NSP_TSFRQST:
			tsfrqst = (struct nsp_tsf_req *) (((char *)buf) + NSP_HDR_LEN);
			wpc_mgr_proctsfreq(buf);
            if (wpc_debug) {
                if (wpc_dbg_log_len + WPCDBGHDR_LEN <= WPC_DBG_SIZE) {
                    dump_wpc_log(__LINE__, nsp_header->frame_type);
                }
                else {
                    printf("wpc log file is full:cannot written\n");
                    return;
                }

            }

			print_tsfrqst(tsfrqst);
			break;
		case NSP_STARETURNTOSLEEPREQ:
			slrqst = (struct nsp_sleep_req *) (((char *)buf) + NSP_HDR_LEN);
            if (wpc_debug) {
                if (wpc_dbg_log_len + WPCDBGHDR_LEN <= WPC_DBG_SIZE) {
                    dump_wpc_log(__LINE__, nsp_header->frame_type);
                }
                else {
                    printf("wpc log file is full:cannot written\n");
                    return;
                }
            }
            else {
                print_slrqst(slrqst);
            }
			break;
       	}
		if(nsp_header->frame_type == NSP_WPCDBGRGST) {
            wpcdbgrqst = (struct nsp_wpc_dbg_resp *) (((char *)buf) + NSP_HDR_LEN);
            print_wpcdbgrqst(wpcdbgrqst);
            if (wpcdbgrqst->dbg_mode) {
                if( !wpc_debug ) { 
                wpc_debug = 1;
                fd = write_dbg_log(fd);
                }
            }
            else {
                if (wpc_debug) {
                wpc_debug = 0;
                stop_dbg_log(fd);
                }
            }
            nsp_hdr.SFD = START_OF_FRAME;
            nsp_hdr.version = NSP_VERSION;
            nsp_hdr.frame_type = NSP_WPCDBGRESP;
            nsp_hdr.frame_length = WPCDBGRESP_LEN;
            memcpy(buf, &nsp_hdr, NSP_HDR_LEN);
	        print_nsp_header(&nsp_hdr);
            wpcdbgresp.request_id = wpcdbgrqst->request_id;
            wpcdbgresp.result = 0;
            memcpy((buf + NSP_HDR_LEN), &wpcdbgresp, WPCDBGRESP_LEN);
            print_wpcdbgresp(&wpcdbgresp);
            write_len = NSP_HDR_LEN + WPCDBGRESP_LEN;
            written = wpc_write(wpc_server_sock, ((char *)buf), write_len);
            if ( written < write_len) {
                // TBD : Need to write pending data if there is partial write 
                printf("Partial write closing connection Size: %d Written: %d\n", sizeof(struct nsp_header)+sizeof(struct nsp_mresp), written);
                wpc_close(wpc_server_sock);
                FD_CLR(wpc_server_sock, &read_fds);
                wpc_server_sock = -1;
            }
        }
        else {
            wpc_nlsendmsg(wpc_driver_sock,nbytes,buf,nlh,&iov,&msg);
        }
	}
}
static int do_cmd(int cmd, port_addr fd)
{
    switch(cmd)
    {
        case 0:
        {
            // Identify command

            // Read the command crc
            uint32_t ccrc;
            serial_read(fd, &ccrc, 4);
            uint32_t eccrc = crc32((void *)0, 0);
            if(ccrc != eccrc)
                return send_error_msg(fd, CRC_ERROR);

            // Set the response length and error code
            uint32_t resp_length = 12;
            uint32_t error_code = SUCCESS;

            // Build the response crc
            uint32_t crc = crc32_start();
            crc = crc32_append(crc, &magic, 4);
            crc = crc32_append(crc, &resp_length, 4);
            crc = crc32_append(crc, &error_code, 4);
            crc = crc32_append(crc, &server_caps, 4);
            crc = crc32_finish(crc);

            // Send the response
            serial_write(fd, &magic, 4);
            serial_write(fd, &resp_length, 4);
            serial_write(fd, &error_code, 4);
            serial_write(fd, &server_caps, 4);
            serial_write(fd, &crc, 4);

            fprintf(stderr, "Sent CMD0 response\n");

            return 0;
        }

        case 1:
        {
            // Read directory
            uint32_t eccrc = crc32_start();

            // Read the directory name
            uint16_t dir_name_len;
            serial_read(fd, &dir_name_len, 2);
            eccrc = crc32_append(eccrc, &dir_name_len, 2);
            char *dir_name = (char *)malloc((int)dir_name_len + 1);
            memset(dir_name, 0, dir_name_len + 1);
            serial_read(fd, dir_name, (size_t)dir_name_len);
            eccrc = crc32_append(eccrc, dir_name, (size_t)dir_name_len);
            eccrc = crc32_finish(eccrc);

            // Read the command crc
            uint32_t ccrc;
            serial_read(fd, &ccrc, 4);
            if(ccrc != eccrc)
                return send_error_msg(fd, CRC_ERROR);

            // Append the requested dir to the base dir
            int full_dir_len = strlen(base_dir) + 1 + dir_name_len + 1;
            char *full_dir = (char *)malloc(full_dir_len);
            memset(full_dir, 0, full_dir_len);
            strcat(full_dir, base_dir);
            strcat(full_dir, "/");
            strcat(full_dir, dir_name);

            // Try and read the requested directory
            DIR *dirp = opendir(full_dir);
            if(dirp == NULL)
            {
                free(dir_name);
                free(full_dir);
                if((errno == ENOENT) || (errno == ENOTDIR))
                    return send_error_msg(fd, PATH_NOT_FOUND);
                else
                    return send_error_msg(fd, UNKNOWN_ERROR);
            }

            // Count the directory entries
            int byte_count = 0;
            uint32_t entry_count = 0;
            struct dirent *de;
            while((de = readdir(dirp)) != NULL)
            {
                // Add space for byte_size, user_id, group_id
                //  and props fields
                byte_count += 16;

                // Add space for name string
                byte_count += 2;
                byte_count += strlen(de->d_name);

                entry_count++;
            }
            rewinddir(dirp);

            // Allocate the buffer to send
            uint8_t *buf = (uint8_t *)malloc(byte_count);
            int bptr = 0;

            // Fill in the buffer
            uint32_t entries_filled = 0;
            while((de = readdir(dirp)) != NULL)
            {
                // Build a string of the whole filename
                int fname_len = strlen(de->d_name);
                int path_len = full_dir_len + 1 + fname_len + 1;
                char *path = (char *)malloc(path_len);
                memset(path, 0, path_len);
                strcat(path, full_dir);
                strcat(path, "/");
                strcat(path, de->d_name);

                // Get the file stats
                struct stat stat_buf;
                if(stat(path, &stat_buf) != 0)
                {
                    fprintf(stderr, "Error running fstat on %s, errno = %i\n",
                            path, errno);
                    free(path);
                    free(buf);
                    free(full_dir);
                    free(dir_name);
                    return send_error_msg(fd, UNKNOWN_ERROR);
                }

                // Fill in the buffer
                write_word((uint32_t)stat_buf.st_size, buf, bptr);
                write_word((uint32_t)stat_buf.st_uid, buf, bptr + 4);
                write_word((uint32_t)stat_buf.st_gid, buf, bptr + 8);
                write_word((uint32_t)stat_buf.st_mode, buf, bptr + 12);
                bptr += 16;

                // Fill in the name
                write_halfword((uint16_t)dir_name_len, buf, bptr);
                bptr += 2;
                memcpy(&buf[bptr], de->d_name, dir_name_len);
                bptr += dir_name_len;

                free(path);

                entries_filled++;
            }
            if(entries_filled != entry_count)
            {
                // An error has occurred re-parsing the directory
                fprintf(stderr, "entries_filled (%i) != entry_count (%i)\n",
                        entries_filled, entry_count);
                free(buf);
                free(dir_name);
                free(full_dir);
                send_error_msg(fd, UNKNOWN_ERROR);
            }

            fprintf(stderr, "SERVER: %i directory entries, byte_count %i\n", entry_count, byte_count);

            // Set the response length and error code
            uint32_t resp_length = 16 + byte_count;
            uint32_t error_code = SUCCESS;
            uint32_t dir_entry_version = 0;

            // Build the response crc
            uint32_t crc = crc32_start();
            crc = crc32_append(crc, &magic, 4);
            crc = crc32_append(crc, &resp_length, 4);
            crc = crc32_append(crc, &error_code, 4);
            crc = crc32_append(crc, &entry_count, 4);
            crc = crc32_append(crc, &dir_entry_version, 4);
            crc = crc32_append(crc, buf, byte_count);
            crc = crc32_finish(crc);

            // Send the response
            serial_write(fd, &magic, 4);
            serial_write(fd, &resp_length, 4);
            serial_write(fd, &error_code, 4);
            serial_write(fd, &entry_count, 4);
            serial_write(fd, &dir_entry_version, 4);
            serial_write(fd, buf, byte_count);
            serial_write(fd, &crc, 4);

            fprintf(stderr, "Sent CMD1 response\n");

            free(buf);
            free(dir_name);
            free(full_dir);

            return 0;
        }
    }
    (void)fd;
    return 0;
}