Пример #1
0
int main(void)
{
    char *str;
    char *cur;
    char ch;
    unsigned int len = 0;

    const unsigned int STR_MAX_LEN = 1024;

    str = (char *)malloc(sizeof(char) * STR_MAX_LEN + 1);
    if (str == NULL) {
        printf("Memory allocate failed!\n");
        exit(EXIT_FAILURE);
    }

    cur = str;
    puts("Enter a string: ");
    while (EOF != (ch = getchar()) && len < STR_MAX_LEN) {
       *cur++ = ch; 
       len++;
    }
    str[len] = '\0';

    bufwrite(str, len);
    free(str);
    
    return 0;
}
Пример #2
0
int main(int argc, char *argv[]) {
	int server;
	int n;
	messagedef_t request, response;
	header_t header;
	void *buf = NULL;

	if (argc != 3) {
		fprintf(stderr, "USAGE: application <server_ip> <port>\n");
		exit(1);
	}

	/* open the TCP socket */
	if ((server = open_connection(argv[1], atoi(argv[2]))) < 0) {
		fprintf(stderr, "ERROR; failed to create socket\n");
		exit(1);
	}

	request.version = VERSION;
	request.command = GET_HDR;
	request.bufsize = 0;

	fprintf(stderr, "------------------------------\n");
	print_request(&request);
	bufwrite(server, &request, sizeof(messagedef_t));

	bufread(server, &response, sizeof(messagedef_t));
	fprintf(stderr, "------------------------------\n");
	print_response(&response);
	fprintf(stderr, "------------------------------\n");

	if (response.command==GET_OK) {
		buf = malloc(response.bufsize);
		if ((n = bufread(server, buf, response.bufsize)) < response.bufsize) {
			fprintf(stderr, "problem reading enough bytes (%d)\n", n);
		}
		else {
			header.def = (headerdef_t *)buf;
			header.buf = (char *) buf+sizeof(headerdef_t);
			print_headerdef(header.def);
		}
		FREE(buf);
	}

	close(server);
	exit(0);
}
Пример #3
0
void
bufrel(long dev, int64_t num, long flush)
{
    struct bufblk *blk = buffindblk(dev, num, 1);

    if (blk) {
#if 0
        if (flush) {
            bufwrite(blk);
        }
#endif
        mtxlk(&buffreelist.lk);
        queuepush(blk, &buffreelist.head);
        mtxunlk(&buffreelist.lk);
    }

    return;
}
Пример #4
0
/* evict buffer; write back to disk */
struct bufblk *
bufevict(void)
{
    struct bufblk *blk = NULL;

    do {
        mtxlk(&buflruqueue.lk);
        blk = queuepop(&buflruqueue.head);
        mtxunlk(&buflruqueue.lk);
        if (!blk) {
            /* TODO: wait for queuepop(&buflruqueue.head) */
        } else {
            if (blk->flg & BUFDIRTY) {
                bufwrite(blk);
            }
            bufclr(blk);
        }
    } while (!blk);
    
    return blk;
}
Пример #5
0
/* this function deals with the incoming client request */
void *tcpsocket(void *arg) {
	int n;
	int status = 0, verbose = 0;
	int oldcancelstate, oldcanceltype;

#ifdef ENABLE_POLLING
	struct pollfd fds;
#endif

	// these are used for communication over the TCP socket
	int client = 0;
	message_t *request = NULL, *response = NULL;

	/* the connection to the client has been made by the server */
	client = (int)arg;

    /* this is for debugging */
    pthread_mutex_lock(&mutexsocketcount);
    socketcount++;
    pthread_mutex_unlock(&mutexsocketcount);

	/* this is to prevent closing the thread at an unwanted moment and memory from leaking */
	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
	pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
	pthread_cleanup_push(cleanup_message, &request);
	pthread_cleanup_push(cleanup_message, &response)
	pthread_cleanup_push(cleanup_socket, &client);

    if (verbose>1) fprintf(stderr, "tcpsocket: client = %d, socketcount = %d, threadcount = %d\n", client, socketcount, threadcount);

	/* keep processing messages untill the connection is closed */
	while (1) {

	request       = (message_t*)malloc(sizeof(message_t));
	request->def  = (messagedef_t*)malloc(sizeof(messagedef_t));
	request->buf  = NULL;

#ifdef ENABLE_POLLING
		/* wait for data to become available or until the connection is closed */
		/* thohar: i think this is not neccessary as we dont need a timeout. */
		/* roboos: we need it to detect when the socket is closed by the client */
		while (1) {
			fds.fd      = client;
			fds.events  = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI | POLLOUT | POLLWRNORM | POLLWRBAND | POLLERR | POLLNVAL;
			fds.revents = 0;

			if (poll(&fds, 1, 1)==-1) {
				perror("poll");
				goto cleanup;
			}

			if (fds.revents & POLLHUP)
				goto cleanup;				// the connection has been closed
			else if (fds.revents & POLLERR)
				goto cleanup;				// the connection has been closed
			else if (fds.revents & POLLIN)
				break;						// data is available, process the message
			else
				usleep(POLLSLEEP);			// wait for data or closed connection
		}
#endif

		if ((n = bufread(client, request->def, sizeof(messagedef_t))) != sizeof(messagedef_t)) {
			if (verbose>0) fprintf(stderr, "tcpsocket: packet size = %d, should be %d\n", n, sizeof(messagedef_t));
			goto cleanup;
		}

		if (request->def->version!=VERSION) {
			if (verbose>0) fprintf(stderr, "tcpsocket: incorrect request version\n");
			goto cleanup;
		}

		if (request->def->bufsize>0) {
			request->buf = malloc(request->def->bufsize);
			if ((n = bufread(client, request->buf, request->def->bufsize)) != request->def->bufsize) {
				if (verbose>0) fprintf(stderr, "tcpsocket: read size = %d, should be %d\n", n, request->def->bufsize);
				goto cleanup;
			}
		}

		if (verbose>1) print_request(request->def);
		if (verbose>1) print_buf(request->buf, request->def->bufsize);

		if ((status = dmarequest(request, &response)) != 0) {
			if (verbose>0) fprintf(stderr, "tcpsocket: an unexpected error occurred\n");
			goto cleanup;
		}

		if (verbose>1) print_response(response->def);
		if (verbose>1) print_buf(request->buf, request->def->bufsize);

		if ((n = bufwrite(client, response->def, sizeof(messagedef_t)))!=sizeof(messagedef_t)) {
			if (verbose>0) fprintf(stderr, "tcpsocket: write size = %d, should be %d\n", n, sizeof(messagedef_t));
			goto cleanup;
		}
		if ((n = bufwrite(client, response->buf, response->def->bufsize))!=response->def->bufsize) {
			if (verbose>0) fprintf(stderr, "tcpsocket: write size = %d, should be %d\n", n, response->def->bufsize);
			goto cleanup;
		}

		cleanup_message(&request);
		cleanup_message(&response);
        request = NULL;
        response = NULL;

	} /* while (1) */

cleanup:
	/* from now on it is safe to cancel the thread */
	pthread_setcancelstate(oldcancelstate, NULL);
	pthread_setcanceltype(oldcanceltype, NULL);

	pthread_cleanup_pop(1); // request
	pthread_cleanup_pop(1); // response
	pthread_cleanup_pop(1); // socket

    /* this is for debugging */
    pthread_mutex_lock(&mutexsocketcount);
    socketcount--;
    pthread_mutex_unlock(&mutexsocketcount);

    /* this is for debugging */
    pthread_mutex_lock(&mutexthreadcount);
    threadcount--;
    pthread_mutex_unlock(&mutexthreadcount);

	pthread_exit(NULL);
	return NULL;
}
Пример #6
0
/*******************************************************************************
 * communicate with the buffer through TCP
 *******************************************************************************/
int tcprequest(int server, const message_t *request, message_t **response_ptr) {
	unsigned int n, total;

	/* this will hold the response */
	message_t *response;
	response      = (message_t*)malloc(sizeof(message_t));
	response->def = (messagedef_t*)malloc(sizeof(messagedef_t));
	response->buf = NULL;
	/* the response should be passed to the calling function, where it should be freed */
	*response_ptr = response;
	
	total = sizeof(messagedef_t) + request->def->bufsize;
	
	/* Check whether request->def and request->buf are already contiguous in memory,
	   or whether request->buf is empty. If that's the case, we can write the request in one go.
	*/
	if (request->def->bufsize == 0 || (request->def+1) == (messagedef_t *) request->buf) {
		if ((n = bufwrite(server, request->def, total)) != total) {
			fprintf(stderr, "write size = %d, should be %d\n", n, total);
			goto cleanup;
		}
	}
	/* Now check whether the total size is below the merge threshold, in which case
	   we'll copy it to contiguous memory and again send it in one go 
	*/
	else if (total <= MERGE_THRESHOLD) {
		char merged[MERGE_THRESHOLD];
		
		memcpy(merged, request->def, sizeof(messagedef_t));
		memcpy(merged + sizeof(messagedef_t), request->buf, request->def->bufsize);
		
		if ((n = bufwrite(server, merged, total)) != total) {
			fprintf(stderr, "write size = %d, should be %d\n", n, total);
			goto cleanup;
		}
	}
	/* Otherwise, send "def" and "buf" in separate pieces. This might introduce latencies
	   if the other end runs Windows :-(
	*/
    else {		
		/* send the request to the server, first the message definition */
		if ((n = bufwrite(server, request->def, sizeof(messagedef_t)))!=sizeof(messagedef_t)) {
			fprintf(stderr, "write size = %d, should be %d\n", n, sizeof(messagedef_t));
			goto cleanup;
		}

		/* send the request to the server, then the message payload */
		if ((n = bufwrite(server, request->buf, request->def->bufsize))!=request->def->bufsize) {
			fprintf(stderr, "write size = %d, should be %d\n", n, request->def->bufsize);
			goto cleanup;
		}
	}

	/* read the response from the server, first the message definition */
	if ((n = bufread(server, response->def, sizeof(messagedef_t))) != sizeof(messagedef_t)) {
		fprintf(stderr, "packet size = %d, should be %d\n", n, sizeof(messagedef_t));
		goto cleanup;
	}

	if (response->def->version!=VERSION) {
		fprintf(stderr, "incorrect version\n");
		goto cleanup;
	}

	/* read the response from the server, then the message payload */
	if (response->def->bufsize>0) {
		response->buf = malloc(response->def->bufsize);
		if ((n = bufread(server, response->buf, response->def->bufsize)) != response->def->bufsize) {
			fprintf(stderr, "read size = %d, should be %d\n", n, response->def->bufsize);
			goto cleanup;
		}
	}

	/* everything went fine, return with the response */
	/* print_response(response->def); */
	return 0;

cleanup:
	/* there was a problem, clear the response and return */
	FREE(response->def);
	FREE(response->buf);
	FREE(response);
	*response_ptr = NULL;  /* SK: this was missing a "*", effectively never really returning 0 */
	return -1;
}
Пример #7
0
/* this function deals with the incoming client request */
void *tcpsocket(void *arg) {
	int n;
	int status = 0, verbose = 0;
	int oldcancelstate, oldcanceltype;

#ifdef ENABLE_POLLING
	struct pollfd fds;
#endif

	/* these are used for communication over the TCP socket */
	int client = 0;
	message_t *request = NULL, *response = NULL;

    threadlocal_t threadlocal;
    threadlocal.message = NULL;
    threadlocal.fd = -1;

	/* the connection to the client has been made by the server */
	client = (int)arg;

    /* this will be closed at cleanup */
    threadlocal.fd = client;

    pthread_cleanup_push(cleanup_tcpsocket, &threadlocal);

    /* this is for debugging */
    pthread_mutex_lock(&mutexsocketcount);
    socketcount++;
    pthread_mutex_unlock(&mutexsocketcount);

    if (verbose>1) fprintf(stderr, "tcpsocket: client = %d, socketcount = %d, threadcount = %d\n", client, socketcount, threadcount);

	/* keep processing messages untill the connection is closed */
	while (1) {
		int swap = 0;
		UINT16_T reqCommand;
		UINT32_T respBufSize;

		request       = (message_t*)malloc(sizeof(message_t));
		DIE_BAD_MALLOC(request);
		
		request->def  = (messagedef_t*)malloc(sizeof(messagedef_t));
		DIE_BAD_MALLOC(request->def);
		request->buf  = NULL;

#ifdef ENABLE_POLLING
		/* wait for data to become available or until the connection is closed */
		/* thohar: i think this is not neccessary as we dont need a timeout. */
		/* roboos: we need it to detect when the socket is closed by the client */
		while (1) {
			fds.fd      = client;
			fds.events  = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI | POLLOUT | POLLWRNORM | POLLWRBAND | POLLERR | POLLNVAL;
			fds.revents = 0;

			if (poll(&fds, 1, 1)==-1) {
				perror("poll");
				goto cleanup;
			}

			if (fds.revents & POLLHUP)
				goto cleanup;				/* the connection has been closed */
			else if (fds.revents & POLLERR)
				goto cleanup;				/* the connection has been closed */
			else if (fds.revents & POLLIN)
				break;						/* data is available, process the message */
			else
				usleep(POLLSLEEP);			/* wait for data or closed connection */
		}
#endif

		if ((n = bufread(client, request->def, sizeof(messagedef_t))) != sizeof(messagedef_t)) {
			if (verbose>0) fprintf(stderr, "tcpsocket: packet size = %d, should be %d\n", n, sizeof(messagedef_t));
			goto cleanup;
		}
		
		if (request->def->version==VERSION_OE) {
			swap = 1;
			ft_swap16(2, &request->def->version); /* version + command */
			ft_swap32(1, &request->def->bufsize);
			reqCommand = request->def->command;		
		}

		if (request->def->version!=VERSION) {
			if (verbose>0) fprintf(stderr, "tcpsocket: incorrect request version\n");
			goto cleanup;
		}
		
		if (request->def->bufsize>0) {
			request->buf = malloc(request->def->bufsize);
			DIE_BAD_MALLOC(request->buf);
			if ((n = bufread(client, request->buf, request->def->bufsize)) != request->def->bufsize) {
				if (verbose>0) fprintf(stderr, "tcpsocket: read size = %d, should be %d\n", n, request->def->bufsize);
				goto cleanup;
			}
		}
		
		if (swap && request->def->bufsize > 0) ft_swap_buf_to_native(reqCommand, request->def->bufsize, request->buf);

		if (verbose>1) print_request(request->def);
		if (verbose>1) print_buf(request->buf, request->def->bufsize);

		if ((status = dmarequest(request, &response)) != 0) {
			if (verbose>0) fprintf(stderr, "tcpsocket: an unexpected error occurred\n");
			goto cleanup;
		}
		
		DIE_BAD_MALLOC(response);
		DIE_BAD_MALLOC(response->def);
		
		if (verbose>1) print_response(response->def);
		if (verbose>1) print_buf(request->buf, request->def->bufsize);
		
		respBufSize = response->def->bufsize;
		if (swap) ft_swap_from_native(reqCommand, response);

		/* we don't need the request anymore */
		cleanup_message((void**)&request);
		request = NULL;
		
		/* merge response->def and response->buf if they are small, so we can send it in one go over TCP */
		if (respBufSize + sizeof(messagedef_t) <= MERGE_THRESHOLD) {
			int msize = respBufSize + sizeof(messagedef_t);
			void *merged = NULL;
			
			append(&merged, 0, response->def, sizeof(messagedef_t));
			DIE_BAD_MALLOC(merged);
			append(&merged, sizeof(messagedef_t), response->buf, respBufSize);
			DIE_BAD_MALLOC(merged);
						
			if ((n=bufwrite(client, merged, msize) != msize)) {
				if (verbose>0) fprintf(stderr, "tcpsocket: write size = %d, should be %d\n", n, msize);
				FREE(merged);
				goto cleanup;
			}
			FREE(merged);
		} else {
			if ((n = bufwrite(client, response->def, sizeof(messagedef_t)))!=sizeof(messagedef_t)) {
				if (verbose>0) fprintf(stderr, "tcpsocket: write size = %d, should be %d\n", n, sizeof(messagedef_t));
				goto cleanup;
			}
			if ((n = bufwrite(client, response->buf, respBufSize))!=respBufSize) {
				if (verbose>0) fprintf(stderr, "tcpsocket: write size = %d, should be %d\n", n, respBufSize);
				goto cleanup;
			}
		}

		cleanup_message((void**)&response);
        response = NULL;

	} /* while (1) */

cleanup:
    printf(""); /* otherwise the pthread_cleanup_pop won't compile */

	if (response!=NULL) 
		cleanup_message((void**)&response);
	response = NULL;	/* SK: prevent double free in following pthread_cleanup_pop */

	pthread_cleanup_pop(1);

    /* this is for debugging */
    pthread_mutex_lock(&mutexsocketcount);
    socketcount--;
    pthread_mutex_unlock(&mutexsocketcount);

    /* this is for debugging */
    pthread_mutex_lock(&mutexthreadcount);
    threadcount--;
    pthread_mutex_unlock(&mutexthreadcount);

	pthread_exit(NULL);
	return NULL;
}
Пример #8
0
int main()
{
	fd_set rfds, wfds, readfds, writefds;
	int n;
	struct buf stdinbuf, stdoutbuf;
	slipconn sc;

	sig_setup();
	login(&sc);
	setuid(0);	/* set real uid to 0 for some ifconfig's */
	slip_start(&sc);

	FD_ZERO(&rfds);
	FD_SET(sc.masterfd, &rfds);
	FD_SET(0, &rfds);
	FD_ZERO(&wfds);

	while (go) {
		readfds = rfds;
		writefds = wfds;

		n = select(sc.masterfd+1, &readfds, &writefds, 0, 0);

		if (n > 0) {
			if (FD_ISSET(0, &readfds)) {
				bufread(&sc, 0, &stdinbuf);
				if (stdinbuf.len == 0) {
					/* eof on stdin */
					slip_stop(&sc);
					exit(0);
				}
				if (stdinbuf.len) {
					FD_SET(sc.masterfd, &wfds);
					FD_CLR(0, &rfds);
				}
			}
			if (FD_ISSET(sc.masterfd, &readfds)) {
				bufread(&sc, sc.masterfd, &stdoutbuf);
				if (stdoutbuf.len) {
					FD_SET(1, &wfds);
					FD_CLR(sc.masterfd, &rfds);
				}
			}
			if (FD_ISSET(sc.masterfd, &writefds)) {
				bufwrite(&sc, sc.masterfd, &stdinbuf);
				if (stdinbuf.len == 0) {
					FD_SET(0, &rfds);
					FD_CLR(sc.masterfd, &wfds);
				}
			}
			if (FD_ISSET(1, &writefds)) {
				bufwrite(&sc, 1, &stdoutbuf);
				if (stdoutbuf.len == 0) {
					FD_SET(sc.masterfd, &rfds);
					FD_CLR(1, &wfds);
				}
			}
		}
	}
	slip_stop(&sc);
	return 0;
}
Пример #9
0
/* the return value is always NULL */
void *tcpsocket(void *arg) {
		int n, jobcount;
		int connect_accept = 1, connect_continue = 1, handshake;
		joblist_t *job;

		/* these are used for communication over the TCP socket */
		int fd = 0;
		message_t *message = NULL;

		threadlocal_t threadlocal;
		threadlocal.message = &message;
		threadlocal.fd      = &fd;

		/* the connection to the client has been made by the server */
		fd = ((int)arg);

		pthread_cleanup_push(cleanup_tcpsocket, &threadlocal);

		/* this is for debugging */
		pthread_mutex_lock(&mutexthreadcount);
		threadcount++;
		pthread_mutex_unlock(&mutexthreadcount);

		/* this is for debugging */
		pthread_mutex_lock(&mutexsocketcount);
		socketcount++;
		pthread_mutex_unlock(&mutexsocketcount);

		/* prevent smartcpu_update during the negociation and reading of the job */
		pthread_mutex_lock(&mutexsmartcpu);
		smartcpu.freeze = 1;
		pthread_mutex_unlock(&mutexsmartcpu);

		/* prevent smartmem_update during the negociation and reading of the job */
		pthread_mutex_lock(&mutexsmartmem);
		smartmem.freeze = 1;
		pthread_mutex_unlock(&mutexsmartmem);

		DEBUG(LOG_DEBUG, "tcpsocket: fd = %d, socketcount = %d, threadcount = %d", fd, socketcount, threadcount);

		pthread_mutex_lock(&mutexjoblist);
		jobcount = 0;
		job = joblist;
		while (job) {
				jobcount++;
				job = job->next;
		}
		pthread_mutex_unlock(&mutexjoblist);

		pthread_mutex_lock(&mutexhost);
		if (host->status==STATUS_MASTER) {
				connect_accept = 1;
		}
		else if (host->status==STATUS_IDLE && jobcount==0) {
				connect_accept = 1;
		}
		else {
				DEBUG(LOG_INFO, "tcpsocket: failed on status (%d) and/or jobcount (%d)", host->status, jobcount);
				connect_accept = 0;
		}
		pthread_mutex_unlock(&mutexhost);

		/* give a handshake */
		handshake = connect_accept || connect_continue;
		if ((n = bufwrite(fd, &handshake, sizeof(int))) != sizeof(int)) {
				DEBUG(LOG_ERR, "tcpsocket: could not write handshake, n = %d, should be %d", n, sizeof(int));
				goto cleanup;
		}

		if (!connect_continue) {
				DEBUG(LOG_INFO, "tcpsocket: dropping connection");
				goto cleanup;
		}

		message       = (message_t*)malloc(sizeof(message_t));
		message->host = (hostdef_t*)malloc(sizeof(hostdef_t));
		message->job  = (jobdef_t*)malloc(sizeof(jobdef_t));
		message->arg  = NULL;
		message->opt  = NULL;

		/* read the host details */
		if ((n = bufread(fd, message->host, sizeof(hostdef_t))) != sizeof(hostdef_t)) {
				DEBUG(LOG_DEBUG, "tcpsocket: read size = %d, should be %d", n, sizeof(hostdef_t));
				goto cleanup;
		}

		/* test whether the version is compatible */
		if (message->host->version!=VERSION) {
				DEBUG(LOG_ERR, "tcpsocket: incorrect host version (%u, %u)", message->host->version, VERSION);
				connect_accept   = 0;
				connect_continue = 0; /* prevent another read request */
		}

		/* determine whether the host, group and user is allowed to execute a job */
		if (message->host->version==VERSION && !security_check(message->host)) {
				DEBUG(LOG_INFO, "tcpsocket: failed security check");
				DEBUG(LOG_DEBUG, "tcpsocket: ismember_userlist  = %d", ismember_userlist(message->host->user));
				DEBUG(LOG_DEBUG, "tcpsocket: ismember_grouplist = %d", ismember_grouplist(message->host->group));
				DEBUG(LOG_DEBUG, "tcpsocket: ismember_hostlist  = %d", ismember_hostlist(message->host->name));
				connect_accept = 0;
		}

		/* give a handshake */
		handshake = connect_accept || connect_continue;
		if ((n = bufwrite(fd, &handshake, sizeof(int))) != sizeof(int)) {
				DEBUG(LOG_ERR, "tcpsocket: could not write handshake, n = %d, should be %d", n, sizeof(int));
				goto cleanup;
		}

		if (!connect_continue) {
				DEBUG(LOG_INFO, "tcpsocket: dropping connection");
				goto cleanup;
		}

		/* read the job details */
		if ((n = bufread(fd, message->job, sizeof(jobdef_t))) != sizeof(jobdef_t)) {
				DEBUG(LOG_ERR, "tcpsocket: packet size = %d, should be %d", n, sizeof(jobdef_t));
				goto cleanup;
		}

		/* test whether the request can be accepted based on the job characteristics */
		if (message->job->version!=VERSION) {
				DEBUG(LOG_ERR, "tcpsocket: incorrect job version (%u, %u)", message->job->version, VERSION);
				connect_accept   = 0;
				connect_continue = 0; /* prevent another read request */
		}

		pthread_mutex_lock(&mutexhost);
		if (message->job->memreq > host->memavail) {
				DEBUG(LOG_INFO, "tcpsocket: memory request too large");
				connect_accept = 0;
		}
		if (message->job->cpureq > host->cpuavail) {
				DEBUG(LOG_INFO, "tcpsocket: cpu request too large");
				connect_accept = 0;
		}
		if (message->job->timreq > host->timavail) {
				DEBUG(LOG_INFO, "tcpsocket: time request too large");
				connect_accept = 0;
		}
		pthread_mutex_unlock(&mutexhost);

		if (message->job->argsize>MAXARGSIZE) {
				DEBUG(LOG_ERR, "tcpsocket: argsize too large");
				connect_accept = 0;
		}

		if (message->job->optsize>MAXARGSIZE) {
				DEBUG(LOG_ERR, "tcpsocket: optsize too large");
				connect_accept = 0;
		}

		/* remember the job characteristics for the smartshare algorithm */
		smartshare_history(message->job);

		/* use a probabilistic approach to determine whether the connection should be dropped */
		if (!smartshare_check(message->job->timreq, message->host->id)) {
				DEBUG(LOG_INFO, "tcpsocket: failed smartshare_check");
				connect_accept = 0;
		}

		/* don't continue reading the content of the job, drop the connection before the job arguments are sent */
		if (!connect_accept)
				connect_continue = 0; /* prevent another read request */

		/* give a handshake */
		handshake = connect_accept || connect_continue;
		if ((n = bufwrite(fd, &handshake, sizeof(int))) != sizeof(int)) {
				DEBUG(LOG_ERR, "tcpsocket: could not write handshake, n = %d, should be %d", n, sizeof(int));
				goto cleanup;
		}

		if (!connect_continue) {
				DEBUG(LOG_INFO, "tcpsocket: dropping connection");
				goto cleanup;
		}

		/* read the job request arguments */
		if (message->job->argsize>0) {
				message->arg = malloc(message->job->argsize);
				if ((n = bufread(fd, message->arg, message->job->argsize)) != message->job->argsize) {
						DEBUG(LOG_ERR, "tcpsocket: read size = %d, should be %d", n, message->job->argsize);
						goto cleanup;
				}
		}

		/* give a handshake */
		handshake = connect_accept || connect_continue;
		if ((n = bufwrite(fd, &handshake, sizeof(int))) != sizeof(int)) {
				DEBUG(LOG_ERR, "tcpsocket: could not write handshake, n = %d, should be %d", n, sizeof(int));
				goto cleanup;
		}

		if (!connect_continue) {
				DEBUG(LOG_INFO, "tcpsocket: dropping connection");
				goto cleanup;
		}

		/* read the job request options */
		if (message->job->optsize>0) {
				message->opt = malloc(message->job->optsize);
				if ((n = bufread(fd, message->opt, message->job->optsize)) != message->job->optsize) {
						DEBUG(LOG_ERR, "tcpsocket: read size = %d, should be %d", n, message->job->optsize);
						goto cleanup;
				}
		}

		/* give a handshake */
		handshake = connect_accept || connect_continue;
		if ((n = bufwrite(fd, &handshake, sizeof(int))) != sizeof(int)) {
				DEBUG(LOG_ERR, "tcpsocket: could not write handshake, n = %d, should be %d", n, sizeof(int));
				goto cleanup;
		}

		if (!connect_continue) {
				DEBUG(LOG_INFO, "tcpsocket: dropping connection");
				goto cleanup;
		}

		/* create a new list item */
		job = (joblist_t *)malloc(sizeof(joblist_t));
		job->job  = message->job;
		job->host = message->host;
		job->arg  = message->arg;
		job->opt  = message->opt;

		pthread_mutex_lock(&mutexjoblist);
		/* add the item to the beginning of the list */
		job->next = joblist;
		joblist = job;

		DEBUG(LOG_DEBUG, "tcpsocket: job.version  = %u", job->job->version);
		DEBUG(LOG_DEBUG, "tcpsocket: job.id       = %u", job->job->id);
		DEBUG(LOG_DEBUG, "tcpsocket: job.argsize  = %u", job->job->argsize);
		DEBUG(LOG_DEBUG, "tcpsocket: job.optsize  = %u", job->job->optsize);
		DEBUG(LOG_DEBUG, "tcpsocket: host.name    = %s", job->host->name);
		DEBUG(LOG_DEBUG, "tcpsocket: host.port    = %u", job->host->port);
		DEBUG(LOG_DEBUG, "tcpsocket: host.id      = %u", job->host->id);

		pthread_mutex_unlock(&mutexjoblist);

cleanup:

		/* from now on it is again allowed to use smartcpu_update */
		pthread_mutex_lock(&mutexsmartcpu);
		smartcpu.freeze = 0;
		pthread_mutex_unlock(&mutexsmartcpu);

		/* from now on it is again allowed to use smartcpu_update */
		pthread_mutex_lock(&mutexsmartmem);
		smartmem.freeze = 0;
		pthread_mutex_unlock(&mutexsmartmem);

		printf(""); /* otherwise the pthread_cleanup_pop won't compile */
		pthread_cleanup_pop(1);
		return NULL;
}
Пример #10
0
int main(int argc, char *argv[]) {
	int server, offset;
	int n;
	messagedef_t request, response;
	event_t event;
	eventsel_t eventsel;
	void *buf = NULL;

	if (argc != 3) {
		fprintf(stderr, "USAGE: application <server_ip> <port>\n");
		exit(1);
	}

	/* open the TCP socket */
	if ((server = open_connection(argv[1], atoi(argv[2]))) < 0) {
		fprintf(stderr, "ERROR; failed to create socket\n");
		exit(1);
	}

	request.version = VERSION;
	request.command = GET_EVT;
	request.bufsize = 0; // sizeof(eventsel_t);

	// eventsel.begevent = 0;
	// eventsel.endevent = 2;

	fprintf(stderr, "------------------------------\n");
	print_request(&request);
	bufwrite(server, &request, sizeof(messagedef_t));
	// write(server, &eventsel, sizeof(eventsel_t));

	bufread(server, &response, sizeof(messagedef_t));
	fprintf(stderr, "------------------------------\n");
	print_response(&response);
	fprintf(stderr, "------------------------------\n");

	if (response.command==GET_OK) {
		buf = malloc(response.bufsize);
		if ((n = bufread(server, buf, response.bufsize)) < response.bufsize) {
			fprintf(stderr, "problem reading enough bytes (%d)\n", n);
		}
		else {
			n = 0;
			offset = 0;
			while (offset<response.bufsize) {
				event.def = (char*)buf+offset;
				event.buf = (char*)buf+offset+sizeof(eventdef_t);
				fprintf(stderr, "\n");
				print_eventdef(event.def);
				
				if (event.def->type_type == DATATYPE_CHAR && event.def->value_type == DATATYPE_CHAR) {
					printf("Type: %.*s  Value: %.*s\n", 
								event.def->type_numel, (char *) event.buf, 
								event.def->value_numel, (char *) event.buf + event.def->type_numel);
				}
				
				offset += sizeof(eventdef_t) + event.def->bufsize;
				n++;
			}
		}
		FREE(buf);
	}

	close(server);
	exit(0);
}
Пример #11
0
int main(int argc, char *argv[]) {
    struct emokit_device* d;
    struct emokit_frame c;

    int32_t i, j, k, nsamp = 0, nblk=0, si=0, status = 0, verbose = 1;
    int32_t putdatrequestsize=0;
    long int elapsedusec=0, printtime=0;
    struct timeval starttime, curtime;
    host_t buffhost;

    /* these represent the acquisition system properties */
    int nchans         = NCHANS;
    int fsample        = FSAMPLE;
    int blocksize      = roundf(fsample/((float)BUFFRATE));
    int channamesize   = 0;
    char *labelsbuf    = NULL;

    /* these are used in the communication and represent statefull information */
    int serverfd             = -1;
    message_t     request;
    char          *requestbuf = NULL;
    data_t        data;
    emokit_samp_t *samples=NULL;
    message_t     *response = NULL;
    messagedef_t  responsedef;
    header_t      header;
    ft_chunkdef_t chunkdef; // for holding the channel names

    if ( argc==1 ) usage();
    if ( argc>1 && (strcmp(argv[1],"-help")==0 || strcmp(argv[1],"-h")==0) ) {
        usage();
        sig_handler(0);
    }

    if (argc>1) {
        char *fname=argv[1];
        int ci=0;
        /* find the which splits the host and port info */
        for (ci=0; fname[ci]!=0; ci++) {
            if ( fname[ci]==':' ) { /* parse the port info */
                buffhost.port=atoi(&(fname[ci+1]));
                break;
            }
        }
        memcpy(buffhost.name,fname,ci);
        buffhost.name[ci]=0; /* copy hostname out and null-terminate */
    }
    else {
        sprintf(buffhost.name, "%s", DEFAULT_HOSTNAME);
        buffhost.port = DEFAULT_PORT;
    }

    if (verbose>0) fprintf(stderr, "emokit2ft: buffer = %s:%d\n", buffhost.name,buffhost.port);

    if ( argc>2 ) {
        BUFFRATE = atoi(argv[2]);
        blocksize = (int)(roundf(fsample/((float)BUFFRATE)));
    }
    if (verbose>0) fprintf(stderr, "emokit2ft: BUFFRATE = %d\n", BUFFRATE);
    if (verbose>0) fprintf(stderr, "emokit2ft: blocksize = %d\n", blocksize);

    //-------------------------------------------------------------------------------
    // open the emotive device
    d = emokit_create();
    k = emokit_get_count(d, EMOKIT_VID, EMOKIT_PID);
    printf("Current epoc devices connected: %d\n", k);
    status=-1;
    if ( k>0 ) {
        for ( i=k-1; i>=0 & i<k; i--) {
            status = emokit_open(d, EMOKIT_VID, EMOKIT_PID, i);
            if(status == 0 ) {
                printf("Connected : %d:%d\n",i,status);
                break;
            } else {
                printf("CANNOT CONNECT: %d:%d\n", i,status);
            }
        }
    }
    if ( status != 0 ) {
        printf("Could not connect to any device\nDo you have permission to read from : /dev/hidrawX\nsee https://github.com/openyou/emokit/issues/89\n");
        return 1;
    }

    //-------------------------------------------------------------------------------
    /* allocate the elements that will be used in the buffer communication */
    request.def = malloc(sizeof(messagedef_t));
    request.buf = NULL;
    request.def->version = VERSION;
    request.def->bufsize = 0;

    header.def = malloc(sizeof(headerdef_t));
    header.buf = NULL; /* header buf contains the channel names */
    //header.buf = labels;

    /* define the header */
    header.def->nchans    = nchans;
    header.def->nsamples  = 0;
    header.def->nevents   = 0;
    header.def->fsample   = fsample;
    header.def->data_type = DATATYPE_EMOKIT;
    header.def->bufsize   = 0;

    //-------------------------------------------------------------------------------
    /* define the stuff for the channel names */
    /* compute the size of the channel names set */
    channamesize=0;
    for( i=0; i<nchans; i++) {
        for ( j=0; labels[i][j]!='\0'; j++);
        j++;
        channamesize+=j;
    }
    /* allocate the memory for the channel names, and copy them into
      it */
    labelsbuf = malloc(WORDSIZE_CHAR*channamesize);
    k=0;
    for( i=0; i<nchans; i++) {
        for ( j=0; labels[i][j]!='\0'; j++,k++) {
            labelsbuf[k]=labels[i][j];
        }
        labelsbuf[k]=labels[i][j];
        k++;
    }
    chunkdef.type = FT_CHUNK_CHANNEL_NAMES;
    chunkdef.size = k;
    // add this info to the header buffer
    header.def->bufsize = append(&header.buf, header.def->bufsize, &chunkdef, sizeof(ft_chunkdef_t));
    header.def->bufsize = append(&header.buf, header.def->bufsize, labelsbuf, chunkdef.size);

    //-------------------------------------------------------------------------------
    /* initialization phase, send the header */
    request.def->command = PUT_HDR;
    request.def->bufsize = append(&request.buf, request.def->bufsize, header.def, sizeof(headerdef_t));
    request.def->bufsize = append(&request.buf, request.def->bufsize, header.buf, header.def->bufsize);

    fprintf(stderr,"emokit2ft: Attempting to open connection to buffer....");
    while ( (serverfd = open_connection(buffhost.name,buffhost.port)) < 0 ) {
        fprintf(stderr, "emokit2ft; failed to create socket. waiting\n");
        usleep(1000000);/* sleep for 1second and retry */
    }
    fprintf(stderr,"done.\nSending header...");
    status = tcprequest(serverfd, &request, &response);
    if (status) {
        fprintf(stderr, "emokit2ft: put header error = %d\n",status);
        sig_handler(-1);
    }
    fprintf(stderr, "done\n");
    free(request.buf);
    free(request.def);
    if (response->def->command != PUT_OK) {
        fprintf(stderr, "emokit2ft: error in 'put header' request.\n");
        sig_handler(-1);
    }
    FREE(response->buf);
    free(response->def);
    free(response);

    /* add a small pause between writing header + first data block */
    usleep(200000);


    //-------------------------------------------------------------------------------
    /* allocate space for the putdata request as 1 block, this contains
      [ request_def data_def data ] */
    putdatrequestsize = sizeof(messagedef_t) + sizeof(datadef_t) + WORDSIZE_EMOKIT*nchans*blocksize;
    requestbuf  = malloc(putdatrequestsize);
    /* define the constant part of the send-data request and allocate space for the variable part */
    request.def = requestbuf ;
    request.buf = request.def + 1; /* N.B. cool pointer arithemetic trick for above! */
    request.def->version = VERSION;
    request.def->command = PUT_DAT;
    request.def->bufsize = putdatrequestsize - sizeof(messagedef_t);
    /* setup the data part of the message */
    data.def            = request.buf;
    data.buf            = data.def + 1; /* N.B. cool pointer arithemetic trick for above */
    samples             = data.buf;     /* version with correct type */
    /* define the constant part of the data */
    data.def->nchans    = nchans;
    data.def->nsamples  = blocksize;
    data.def->data_type = DATATYPE_EMOKIT;
    data.def->bufsize   = WORDSIZE_EMOKIT * nchans * blocksize;

    //-------------------------------------------------------------------------------
    // Loop sending the data in blocks as it becomes available
    gettimeofday(&starttime,NULL); /* get time we started to compute delay before next sample */
    while (1) {

        //-------------------------------------------------------------------------------
        for ( si=0; si<blocksize; si++) { // get a block's worth of samples
            // wait until new data to get, 4 milliSec N.B. inter-sample ~= 8 milliSec
            while( emokit_read_data(d)<=0 ) {
                usleep(2000);
            }
            /* get the new data */
            c = emokit_get_next_frame(d);
            if ( verbose>1 ) {
                printf("%5d) %5d\t%5d\t%5d\t%5d\t%5d\t%5d\n", nsamp, c.counter, c.gyroX, c.gyroY, c.F3, c.FC6, c.P7);
                fflush(stdout);
            }
            // copy the samples into the data buffer, in the order we
            // *said* they should be
            samples[(si*nchans)+0] =c.counter;
            samples[(si*nchans)+1] =(c.AF3 - eeg_zero_offset)*eeg_scale;
            samples[(si*nchans)+2] =(c.F7  - eeg_zero_offset)*eeg_scale;
            samples[(si*nchans)+3] =(c.F3  - eeg_zero_offset)*eeg_scale;
            samples[(si*nchans)+4] =(c.FC5 - eeg_zero_offset)*eeg_scale;
            samples[(si*nchans)+5] =(c.T7  - eeg_zero_offset)*eeg_scale;
            samples[(si*nchans)+6] =(c.P7  - eeg_zero_offset)*eeg_scale;
            samples[(si*nchans)+7] =(c.O1  - eeg_zero_offset)*eeg_scale;
            samples[(si*nchans)+8] =(c.O2  - eeg_zero_offset)*eeg_scale;
            samples[(si*nchans)+9] =(c.P8  - eeg_zero_offset)*eeg_scale;
            samples[(si*nchans)+10]=(c.T8  - eeg_zero_offset)*eeg_scale;
            samples[(si*nchans)+11]=(c.FC6 - eeg_zero_offset)*eeg_scale;
            samples[(si*nchans)+12]=(c.F4  - eeg_zero_offset)*eeg_scale;
            samples[(si*nchans)+13]=(c.F8  - eeg_zero_offset)*eeg_scale;
            samples[(si*nchans)+14]=(c.AF4 - eeg_zero_offset)*eeg_scale;
            samples[(si*nchans)+15]=c.gyroX;
            samples[(si*nchans)+16]=c.gyroY;
            nsamp+=1;/*nsamp; */
        }

        //-------------------------------------------------------------------------------
        /* send the data to the buffer */
        /* 0. If send data already read response to previous put-data */
        if ( nblk > 0 ) {
            if ( readresponse(serverfd,&responsedef) !=0 ||
                    responsedef.command != PUT_OK ) {
                fprintf(stderr,"emokit2ft: Error writing samples.\n");
            }
        }

        /* 1. Send the new data, but don't wait for a response */
        if ((k = bufwrite(serverfd, request.def, putdatrequestsize)) != putdatrequestsize) {
            fprintf(stderr, "write size = %d, should be %d\n", k, putdatrequestsize);
            sig_handler(-1);
        }

        /* do some logging */
        gettimeofday(&curtime,NULL);
        elapsedusec=(curtime.tv_usec + 1000000 * curtime.tv_sec) - (starttime.tv_usec + 1000000 * starttime.tv_sec);
        if ( elapsedusec / 1000000 >= printtime ) {
            fprintf(stderr,"%d %d %d %f (blk,samp,event,sec)\r",nblk,nsamp,0,elapsedusec/1000000.0);
            printtime+=10;
        }
        nblk+=1;
    } /* while(1) */

    // free all the stuff we've allocated
    free(labelsbuf);
    free(requestbuf);
}