Beispiel #1
0
void listGames(player p) {
    int j;

    if(nb_game == 0) {
        sendack(p->fd, CMD_LIST, NULL);
        return;
    }

    // initialize message
    char * msg = malloc(sizeof(char)*(nb_game*(5+MAX_NAME_SIZE)+nb_game - 1));
    *msg = 0;

    // for each game
    for(j=0;j<nb_game;j++) {
        char tmp[6];
        // print id and game master's name
        sprintf(tmp, "#%05d", games[j]->id);
        strcat(msg, tmp);
        if(games[j]->game_master != NULL)
            strcat(msg, games[j]->game_master->name);
    }

    sendack(p->fd, CMD_LIST, msg);
    free(msg);
}
Beispiel #2
0
// Parse the answers of the child processes transferring files
void parseFileProcessesRequest(int i, char * buffer) {
    // if the fd closed
    if(readline(fileprocesses[i]->in, buffer, MAXBUF-1) == 0) {
        printf("\rChild process MIA...\n");
        senderror(fileprocesses[i]->sender->fd, CMD_FILE, ERR_INTERNAL);
        removeChildProcess(i);
        return;
    }

    if(buffer[3] != '#') {
        printf("\rChild process is sending strange commands... Better check that, bro.\n");
        senderror(fileprocesses[i]->sender->fd, CMD_FILE, ERR_INTERNAL);
        removeChildProcess(i);
        return;
    }

    buffer[3] = 0;
    if(strcmp(buffer, CMD_ERR) == 0) {
        printf("\rChild process failed with error: %s\n", buffer+4);
        senderror(fileprocesses[i]->sender->fd, CMD_FILE, ERR_INTERNAL);
        removeChildProcess(i);
        return;
    }

    if(strcmp(buffer, CMD_PORT) == 0 && buffer[9] == '#') {
        char * msg = malloc(sizeof(char)*(6+strlen(buffer+4)));
        buffer[9] = 0;
        printf("\rChild process waiting on port %s\n", buffer+4);
        sprintf(msg, "%s#%s#%s\n", CMD_PORT, buffer+4, buffer+10);
        sendline(fileprocesses[i]->sender->fd, msg);
        free(msg);
        return;
    }

    if(strcmp(buffer, CMD_READY) == 0) {
        printf("\rFile successfully uploaded !\n");
        int j;
        char * msg = malloc(sizeof(char)*(6+strlen(buffer+4)));
        sprintf(msg, "%s#%s\n", CMD_FILE, buffer+4);
        for(j=0; j<fileprocesses[i]->sender->game->nb_players; j++)
            if(fileprocesses[i]->sender->game->players[j] != fileprocesses[i]->sender)
                sendline(fileprocesses[i]->sender->game->players[j]->fd, msg);
        sprintf(msg, "%05d", fileprocesses[i]->sender->game->nb_players);
        sendack(fileprocesses[i]->out, NULL, msg);
        free(msg);
        return;
    }

    if(strcmp(buffer, CMD_ACK) == 0) {
        printf("\rFile successfully broadcasted !\n");
        sendack(fileprocesses[i]->sender->fd, CMD_FILE, buffer+4);
        removeChildProcess(i);
        return;
    }
}
Beispiel #3
0
// send an available game id
void getAvailableId(player p) {
    int j,k;

    int r=rand()%99999;
    int id;
    for(k=0;k<99999;k++) {
        int exist = 0;
        id = (r+k)%99999+1;
        for(j=0;j<nb_game; j++)
            if(games[j]->id == id) {
                exist = 1;
                break;
            }
        if(!exist)
            break;
    }

    // No available id found
    if(k == 99999) {
        sendline(p->fd, "ERR#WTF ?? No more ids available ?!\n");
        return;
    }

    char msg[6];
    sprintf(msg, "%05d\n", id);
    sendack(p->fd, CMD_CREATE, msg);
}
Beispiel #4
0
// bind to a game
void bindToGame(player p, char * buffer) {
    int j;
    buffer[9] = 0;

    // already in a game
    if(p->game) {
        senderror(p->fd, NULL, ERR_ALREADY_IN_GAME);
        return;
    }

    // id of the game
    int id = atoi(buffer+4);

    // search for the game
    game g = NULL;
    for(j=0; j<nb_game; j++)
        if(games[j]->id == id) {
            g = games[j];
            break;
        }

    // if it doesn't exist, 
    if(!g) {
        senderror(p->fd, CMD_BIND, ERR_GAME_DOESNT_EXIST);
        return;
    }

    // update the name of the player
    strncpy(p->name, buffer+10, MAX_NAME_SIZE);

    // if game is already full
    if(g->nb_players >= MAX_PLAYER_GAME) {
        printf("\rToo many players in this game !\n");
        senderror(p->fd, CMD_BIND, ERR_TOO_MANY_PLAYERS_IN_GAME);
        return;
    }

    // check if the name is already used
    for(j=0; j<g->nb_players; j++)
        if(strcmp(g->players[j]->name, p->name) == 0) {
            printf("\rName already used !\n");
            senderror(p->fd, CMD_BIND, ERR_NAME_USED);
            return;
        }

    // send notification to players in the game
    char * msg = malloc(sizeof(char)*(6+strlen(p->name)));
    sprintf(msg, "%s#%s\n", CMD_CONNECTED, p->name);
    for(j=0;j<g->nb_players; j++)
        if(g->players[j] != p)
            sendline(g->players[j]->fd, msg);
    free(msg);

    // update player, game and table of games
    p->game = g;
    g->players[g->nb_players] = p;
    g->nb_players++;
    sendack(p->fd, CMD_BIND, buffer+4);
}
Beispiel #5
0
/*
 * Receives TCP data until socket breaks or File is completely received
 * int recvsock -> The listening UDP socket
 * int tcpsock  -> The TCP ACK port
 * FILE *fout   -> The file to write data too
 * FILE *log    -> The log file to write received packet data
 */
size_t recv_tcp(int recvsock, int tcpsock, FILE *fout, FILE *log) {
    /* No more data to read */
    if (finflag) {
        finflag = 0;
        return 0;
    }
    struct timeval tv;
    ssize_t len = 0;
    uint16_t src, dst;
    struct sockaddr_storage src_addr;
    socklen_t src_len = sizeof(src_addr);
    /* Packet and ACK bookkeeping */
    uint32_t expected_seq = 0;
    uint32_t totalsent = 0;
    uint32_t lastpkt_len = 0;
    /* Packet Priority Queue for packet buffering */
    std::priority_queue<Packet *, std::vector<Packet *>, PacketCompare> pq;
    for(;;) {
        if (finflag && pq.empty()) {
            return totalsent;
        }
        uint8_t packet_data[MSS + HEADLEN];
        if ((len = recvfrom(recvsock, packet_data, MSS + HEADLEN, NOFLAG,
                            (struct sockaddr *) &src_addr, &src_len)) <= 0) {
            if (errno == EAGAIN) {
                continue;
            } else {
                perror("recvfrom() failed");
                return 0;
            }
        }
        Packet *pkt = new Packet(packet_data, (size_t) len);
        src = pkt->get_srcport();
        dst = pkt->get_dstport();
        gettimeofday(&tv, NULL);
        char *logtime = ctime(&(tv.tv_sec));
        logtime[strlen(logtime) - 1] = '\0';
        /* Checksum doesn't match */
        if (!(pkt->check_checksum((size_t) len))) {
            if(log != nullptr) {
                fprintf(log, "FAILURE %s %u %u %u %u %d\n", logtime, src, dst,
                        pkt->get_seq(), pkt->get_ack(), pkt->get_flags());
            }
            /* Update Timeout */
            check_timeout(&tv);
            /* Send old ack for fast retransmit */
            if (sendack(tcpsock, dst, src, expected_seq) != HEADLEN) {
                if (!finflag) {
                    die_with_err("send failed");
                }
            }
            delete pkt;
            continue;
        }
        if(log != nullptr) {
            fprintf(log, "SUCCESS %s %u %u %u %u %d\n", logtime, src, dst,
                    pkt->get_seq(), pkt->get_ack(), pkt->get_flags());
        }
        if (!finflag) {
            finflag = (pkt->get_flags() & FINFLAG);
            /* Sets the length of the last packet for final packet handeling */
            lastpkt_len = (uint32_t)len-HEADLEN;
        }
        if (expected_seq == pkt->get_seq()) {
            /* Writes data to file output skipping the header */
            fwrite(pkt->get_data()+HEADLEN, sizeof(uint8_t),
                   (size_t)len - HEADLEN, fout);
            expected_seq += len - HEADLEN;
            totalsent += len - HEADLEN;
            delete pkt;
            /* Writes buffered data to file if the sequence number matches */
            while (!pq.empty() && (pq.top())->get_seq() == expected_seq) {
                pkt = pq.top();
                size_t size = (size_t)((pkt->get_flags() & FINFLAG)
                                       ? lastpkt_len : MSS);
                fwrite(pkt->get_data()+HEADLEN, sizeof(uint8_t), size, fout);
                totalsent += size;
                expected_seq += size;
                delete pkt;
                pq.pop();
            }
        } else if(expected_seq < pkt->get_seq()) { // Out of order packet
            pq.push(pkt);
        } else { // Already written, delete
            delete pkt;
        }
        if (sendack(tcpsock, dst, src, expected_seq) != HEADLEN) {
            if (!finflag) {
                die_with_err("send failed");
            }
        }
    }
    return totalsent;
}
Beispiel #6
0
/**
 * @breaf initialize the pfon comunication
 *
 * @param no parametrs
 */
int8_t FON_INIT()
{
	enum fbus_frametype ftype;
	char buffer[24];
	memset(buffer, 0, sizeof(buffer));

	//write mesage in EEPPROM
	/*
	 eeprom_read_block(buffer, (int*) 486, 18);
	 if (strlen(buffer) == 0)
	 {
	 strcpy_P(buffer, CMD_ERR);
	 eeprom_write_block(buffer, (int*) 486, 18);
	 //strcpy_P(buffer, 0x00);
	 }
	 */

	SetPort();
	strcpy_P(buffer, CMD_ERR);
	eeprom_update_block(buffer, (int*) 486, 18);

	uint8_t init[] =
	{ 0x00, 0x01, 0x64, 0x01, 0x01, 0x40 };
	fbus_init();
	sendframe(0x40, init, 6);
	ftype = fbus_readack();
	if (ftype == FRAME_UNKNOWN)
	{
		sendframe(0x40, init, 6);
		ftype = fbus_readack();
		if (ftype == FRAME_UNKNOWN)
		{
			sendframe(0x40, init, 6);
			ftype = fbus_readack();
			if (ftype == FRAME_UNKNOWN)
			{
				PORTB |= (1 << PB5); //eror
				return 0;
			}
		}
	}

	//save smsc number if is not saved
	char smsc_nr[18];
	memset(smsc_nr, 0, sizeof(smsc_nr));
	_delay_ms(1000);
	fbus_getsmsc(smsc_nr);

	/*
	 eeprom_read_block(buffer, (int*) 360, 18);
	 if ((strcmp(smsc_nr, buffer) != 0) && (strlen(smsc_nr) != 0))
	 eeprom_write_block(smsc_nr, (int*) 360, 18);
	 */
	if (strlen(smsc_nr) != 0)
		eeprom_update_block(smsc_nr, (int*) 360, 18);

	sendack(0x02, 0x04);

	uint8_t init_sms[] =
	{ 0x00, 0x01, 0x00, 0x07, 0x02, 0x01, 0x01, 0x64, 0x01, 0x47 };
	sendframe(0x02, init_sms, 0x0a);
	//fbus_readack();
	sendack(0x14, 0x00);
	//uart_sendsms("+40744946000", "+40745183841", smsc_nr);
	return 1;
}
Beispiel #7
0
// transfer a file
// for the son, never return
void transfer_file(player p, char * buffer) {
    int out[2], in[2];
    int childpid;
    int size;
    char * filepath;
    buffer[10] = 0;

    // if in a game
    if(!p->game) {
        senderror(p->fd, CMD_FILE, ERR_NOT_IN_GAME);
        return;
    }

    // if there is no game master or if the player is not game master
    if(p->game->game_master != p) {
        senderror(p->fd, CMD_FILE, ERR_ONLY_GM);
        return;
    }

    // check for file size
    if((size = atoi(buffer+4)) > MAX_FILE_SIZE) {
        senderror(p->fd, CMD_FILE, ERR_FILE_TOO_BIG);
        return;
    }

    // path of the file is specified
    if(strlen(buffer+11) == 0) {
        senderror(p->fd, NULL, ERR_NOT_RECOGNIZED);
        return;
    }

    filepath = malloc(sizeof(char)*(strlen(buffer+11)+1));
    strcpy(filepath, buffer+11);
    printf("\rPlayer %s is trying to broadcast the file : %s (%dB)\n", p->name, filepath, size);

    // The file can be transmitted
    if(nb_file_processes >= MAX_FILE_TRANSFER) {
        printf("\rToo many ongoing file transfers !\n");
        senderror(p->fd, CMD_FILE, ERR_TOO_MANY_FILE_TRANSFERS);
        return;
    }

    // create a pipe to communicate between the two processes
    pipe(in);
    pipe(out);

    // fork
    if((childpid = fork()) == -1) {
        printf("\rServer failed to fork !\n");
        senderror(p->fd, CMD_FILE, ERR_INTERNAL);
        return;
    }

    // for the child
    if(childpid == 0) {
        // close the input part of one pipe and the output part of the other one
        close(out[0]);
        close(in[1]);

        // create the listening socket
        int filelistener = socket(AF_INET, SOCK_STREAM, 0);
        if(filelistener == -1) {
            senderror(out[1], NULL, "Could not open socket");
            exit(EXIT_FAILURE);
        }
        // enable to reuse addr right after we stopped the server
        int optval = 1;
        setsockopt(filelistener, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));

        struct    sockaddr_in servaddr;  // socket address struct 
        memset(&servaddr, 0, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        servaddr.sin_port = htons(0);

        // bind socket
        if(bind(filelistener, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
            senderror(out[1], NULL, "Error when trying to bind !");
            exit(EXIT_FAILURE);
        }

        // get port
        socklen_t length = sizeof(servaddr);
        getsockname(filelistener, (struct sockaddr *)&servaddr, &length);
        int port = ntohs(servaddr.sin_port);

        // Listen on the port
        if(listen(filelistener, MAX_PLAYER_GAME+2) == -1) {
            senderror(out[1], NULL, "Error when trying to listen !");
            exit(EXIT_FAILURE);
        }

        // send port to parent
        char * msg = malloc(sizeof(char)*(12+strlen(filepath)));
        sprintf(msg, "%s#%05d#%s\n", CMD_PORT, port, filepath);
        sendline(out[1], msg);
        free(msg);

        // wait for the connection of the sender
        fd_set rfds;
        FD_ZERO(&rfds);
        FD_SET(filelistener, &rfds);
        int fd_max;
        fd_max = filelistener;
        struct timeval to = {TIMEOUT_FILE, 0};
        if(select(fd_max+1, &rfds, NULL, NULL, &to) < 0) {
            senderror(out[1], NULL, "Error when trying to select !");
            exit(EXIT_FAILURE);
        }

        int sender_socket;
        if(FD_ISSET(filelistener, &rfds)) {
            struct 	  sockaddr_in csin;
            socklen_t recsize = sizeof(csin);
            sender_socket = accept(filelistener, (struct sockaddr *) &csin, &recsize);
        }
        else {
            senderror(out[1], NULL, "Timeout before sender tries to connect !");
            exit(EXIT_FAILURE);
        }

        // get the file from the sender
        char filename[12+MAX_NAME_SIZE];
        sprintf(filename, "/tmp/%05d_%s", p->game->id, p->name);
        int serverfile = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
        int sent = 0;
        while(sent < size) {

            // prepare the set
            fd_set rfds;
            FD_ZERO(&rfds);
            FD_SET(sender_socket, &rfds);
            fd_max = sender_socket;
            to.tv_sec = TIMEOUT_FILE;
            to.tv_usec = 0;

            if(select(fd_max+1, &rfds, NULL, NULL, &to) < 0) {
                senderror(out[1], NULL, "Error when trying to select !");
                close(serverfile);
                unlink(filename);
                exit(EXIT_FAILURE);
            }

            if(FD_ISSET(sender_socket, &rfds)) {
                int rc = read(sender_socket, buffer, MAXBUF);
                if(write(serverfile, buffer, rc) < 0) {
                    senderror(out[1], NULL, "Error when writing to tmp file !");
                    close(serverfile);
                    unlink(filename);
                    exit(EXIT_FAILURE);
                }
                sent += rc;
            }
            else {
                senderror(out[1], NULL, "Timeout when sender was sending data");
                close(serverfile);
                unlink(filename);
                exit(EXIT_FAILURE);
            }
        }
        close(serverfile);
        close(sender_socket);

        // send notification to the parent that we are ready to broadcast
        msg = malloc(sizeof(char)*(19+strlen(filepath)));
        sprintf(msg, "%s#%05d#%06d#%s\n", CMD_READY, port, size, filepath);
        sendline(out[1], msg);
        readline(in[0], buffer, MAXBUF);
        if(buffer[3] != '#') {
            senderror(out[1], NULL, "Who are you ?");
            unlink(filename);
            exit(EXIT_FAILURE);
        }
        buffer[3] = 0;
        if(strcmp(buffer, CMD_ACK) != 0) {
            senderror(out[1], NULL, "Who are you ?");
            unlink(filename);
            exit(EXIT_FAILURE);
        }
        int nb_players = atoi(buffer+4);

        // send the file to the other players
        int connected_clients = 0, served_clients = 0;
        int * sock_client = malloc(sizeof(int)*nb_players);
        int * fd_client = malloc(sizeof(int)*nb_players);
        int * byte_written = malloc(sizeof(int)*nb_players);

        while(served_clients < nb_players-1) {
            fd_set rfds;
            fd_set rfds_write;
            FD_ZERO(&rfds);
            FD_ZERO(&rfds_write);
            FD_SET(filelistener, &rfds);
            fd_max = filelistener;
            int j;
            for(j=0; j<connected_clients; j++) {
                FD_SET(sock_client[j], &rfds_write);
                if(sock_client[j] > fd_max)
                    fd_max = sock_client[j];
            }
            to.tv_sec = TIMEOUT_FILE;
            to.tv_usec = 0;
            int return_value;

            if((return_value = select(fd_max+1, &rfds, &rfds_write, NULL, &to)) < 0) {
                senderror(out[1], NULL, "Error when trying to select !");
                unlink(filename);
                exit(EXIT_FAILURE);
            }
            if(return_value == 0) {
                senderror(out[1], NULL, "Timeout clients");
                unlink(filename);
                exit(EXIT_FAILURE);
            }

            if(FD_ISSET(filelistener, &rfds)) {
                struct 	  sockaddr_in csin;
                socklen_t recsize = sizeof(csin);
                int s = accept(filelistener, (struct sockaddr *) &csin, &recsize);
                if(connected_clients < nb_players) {
                    sock_client[connected_clients] = s;
                    fd_client[connected_clients] = open(filename, O_RDONLY);
                    byte_written[connected_clients] = 0;
                    connected_clients ++;
                }
                else
                    close(s);
            }

            for(j=0; j<connected_clients; j++)
                if(FD_ISSET(sock_client[j], &rfds_write)) {
                    int b_read = read(fd_client[j], buffer, size-byte_written[j] < MAXBUF ? size-byte_written[j] : MAXBUF);
                    int b_written = write(sock_client[j], buffer, b_read);
                    if(b_written == 0) {
                        close(sock_client[j]);
                        close(fd_client[j]);
                        int k;
                        for(k=j; k<connected_clients-1; k++) {
                            fd_client[k] = fd_client[k+1];
                            sock_client[k] = sock_client[k+1];
                            byte_written[k] = byte_written[k+1];
                        }
                    }
                    lseek(sock_client[j], b_written-b_read, SEEK_CUR);
                    byte_written[j] += b_written;
                    if(byte_written[j] == size) {
                        close(sock_client[j]);
                        close(fd_client[j]);
                        int k;
                        for(k=j; k<connected_clients-1; k++) {
                            fd_client[k] = fd_client[k+1];
                            sock_client[k] = sock_client[k+1];
                            byte_written[k] = byte_written[k+1];
                        }
                        served_clients++;
                        connected_clients--;
                        j--;
                    }

                }
        }
        sendack(out[1], NULL, filepath);
        unlink(filename);
        exit(0);
    }
    // for the parent
    else {
        // close output part of the pipe and input part of the other
        close(out[1]);
        close(in[0]);

        // create a new entry in the child processes table
        fileprocesses[nb_file_processes] = malloc(sizeof(struct _fproc));
        fileprocesses[nb_file_processes]->in = out[0];
        fileprocesses[nb_file_processes]->out = in[1];
        fileprocesses[nb_file_processes]->sender = p;
        fileprocesses[nb_file_processes]->pid = childpid;
        nb_file_processes++;
        free(filepath);

        return;
    }
}