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; }
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); }
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; }
/* 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; }
/* 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; }
/******************************************************************************* * 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; }
/* 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; }
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; }
/* 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; }
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); }
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); }