Пример #1
0
int main(int argc, char const *argv[])
{	
	char *ip, *port;
	get_input(argc, argv, &ip, &port);
	printf("IP = %s\n", ip);
	printf("Port = %s\n", port);

	int sock;
	sock = create_socket(SOCK_DGRAM, ip);
	

/* PROTOTIPO de como ENVIA mensagens */
	char msg[BUF_SIZE];
	strcat(msg, "GET /index.html HTTP/1.1\r\nHost: ");
	strcat(msg, ip);
	strcat(msg, "\r\n\r\n");
	print_request(msg);

	send_all(sock, msg);

/* PROTOTIPO de como RECEBE mensagens */
	// int recv(int sockfd, void *buf, int len, int flags);
	char *buff;
	size_t by_recv;
	by_recv = recv_all(sock, &buff, BUF_SIZE);

	print_response(buff);
	return 0;
}
Пример #2
0
/*******************************************************************************
 * this function is called by the client
 * it takes care that the request is processed by the buffer
 *******************************************************************************/
int clientrequest(int server, const message_t *request, message_t **response_ptr) {
    int verbose = 0;

	if (verbose>0) fprintf(stderr, "clientrequest: server = %d\n", server);
	if (verbose>0) print_request(request->def);

	if (server<0) {
		fprintf(stderr, "clientrequest: invalid value for server (%d)\n", server);
		return -1;
	}

	else if (server==0) {
		/* use direct memory acces to the buffer */
		if (dmarequest(request, response_ptr)!=0)
			return -2;
	}

	else if (server>0) {
		/* use TCP connection to the buffer */
		if (tcprequest(server, request, response_ptr)!=0)
			return -3;
	}

	if (verbose>0) print_response((*response_ptr)->def);

	/* everything went fine */
	return 0;
}
Пример #3
0
static void
soup_logger_request_started (SoupSessionFeature *feature,
			     SoupSession *session,
			     SoupMessage *msg,
			     SoupSocket *socket)
{
	SoupLogger *logger = SOUP_LOGGER (feature);
	gboolean restarted;
	guint msg_id;

	g_return_if_fail (SOUP_IS_SESSION (session));
	g_return_if_fail (SOUP_IS_MESSAGE (msg));
	g_return_if_fail (SOUP_IS_SOCKET (socket));

	msg_id = soup_logger_get_id (logger, msg);
	if (msg_id)
		restarted = TRUE;
	else {
		soup_logger_set_id (logger, msg);
		restarted = FALSE;
	}

	if (!soup_logger_get_id (logger, session))
		soup_logger_set_id (logger, session);

	if (!soup_logger_get_id (logger, socket))
		soup_logger_set_id (logger, socket);

	print_request (logger, msg, session, socket, restarted);
	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, ' ', "");
}
Пример #4
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);
	write(server, &request, sizeof(messagedef_t));
	// write(server, &eventsel, sizeof(eventsel_t));

	read(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 = buf+offset;
				event.buf = buf+offset+sizeof(eventdef_t);
				fprintf(stderr, "\n");
				print_eventdef(event.def);
				offset += sizeof(eventdef_t) + event.def->bufsize;
				n++;
			}
		}
		FREE(buf);
	}

	close(server);
	exit(0);
}
Пример #5
0
int buffer_gethdr(int server, mxArray *plhs[], const mxArray *prhs[])
{
	int verbose = 0;
	int result  = 0;

	message_t *request  = NULL;
	message_t *response = NULL;

	/* this is for the Matlab specific output */
	const char *field_names[NUMBER_OF_FIELDS] = {"nchans", "nsamples", "nevents", "fsample", "data_type", "bufsize"};

	/* allocate the elements that will be used in the communication */
	request      = malloc(sizeof(message_t));
	request->def = malloc(sizeof(messagedef_t));
	request->buf = NULL;
	request->def->version = VERSION;
	request->def->command = GET_HDR;
	request->def->bufsize = 0;
	
	if (verbose) print_request(request->def);
	result = clientrequest(server, request, &response);
	
	if (result == 0) {
		if (verbose) print_response(response->def);

		if (response->def->command==GET_OK) {
			headerdef_t *headerdef = (headerdef_t *) response->buf;
			
			if (verbose) print_headerdef(headerdef);

			plhs[0] = mxCreateStructMatrix(1, 1, NUMBER_OF_FIELDS, field_names);
			mxSetFieldByNumber(plhs[0], 0, 0, mxCreateDoubleScalar((double)(headerdef->nchans)));
			mxSetFieldByNumber(plhs[0], 0, 1, mxCreateDoubleScalar((double)(headerdef->nsamples)));
			mxSetFieldByNumber(plhs[0], 0, 2, mxCreateDoubleScalar((double)(headerdef->nevents)));
			mxSetFieldByNumber(plhs[0], 0, 3, mxCreateDoubleScalar((double)(headerdef->fsample)));
			mxSetFieldByNumber(plhs[0], 0, 4, mxCreateDoubleScalar((double)(headerdef->data_type)));
			mxSetFieldByNumber(plhs[0], 0, 5, mxCreateDoubleScalar((double)(headerdef->bufsize)));
			
			addChunksToMatrix(plhs[0], (const char *) response->buf + sizeof(headerdef_t), headerdef->bufsize, headerdef->nchans);
		}
		else {
			result = response->def->command;
		}
	}

	if (response) {
		FREE(response->def);
		FREE(response->buf);
		FREE(response);
	}

	if (request) {
		FREE(request->def);
		FREE(request->buf);
		FREE(request);
	}

	return result;
}
Пример #6
0
void print_packet(corefs_packet pkt){
   dprintf(stderr, "--------------------------------------------------------\n");
  dprintf(stderr,"<header>\n");
  dprintf(stderr, "\t| magic[0x%x] | type[0x%x] | sequence[0x%x] | payload_size[0d%u] |\n",pkt.header.magic, pkt.header.type, pkt.header.sequence, pkt.header.payload_size);
  dprintf(stderr,"<\\header>\n");
  dprintf(stderr, "--------------------------------------------------------\n");
  if(pkt.header.type == COREFS_REQUEST) print_request(pkt);
  if(pkt.header.type == COREFS_RESPONSE) print_response(pkt);
}
Пример #7
0
static void
send_raw_data (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
{
  Call *call;

  assert (et == EV_CALL_SEND_RAW_DATA && object_is_call (obj));
  call = (Call *) obj;

  print_request (call);
}
Пример #8
0
int
main()
{
	struct sockaddr_in from;
	socklen_t from_size = (socklen_t)sizeof (from);
	int cc;
	int name_length = sizeof (hostname);
	fd_set rfds;
	struct timeval tv;

	(void) sysinfo(SI_HOSTNAME, hostname, name_length);

	for (;;) {
		tv.tv_sec = MAX_LIFE;
		tv.tv_usec = 0;
		FD_ZERO(&rfds);
		FD_SET(0, &rfds);
		if (select(1, &rfds, 0, 0, &tv) <= 0)
			return (0);
		cc = recvfrom(0, (char *)&request, sizeof (request), 0,
		    (struct sockaddr *)&from, &from_size);

		if (cc != sizeof (request)) {
			if (cc < 0 && errno != EINTR) {
				print_error("receive");
			}
		} else {

			if (debug) {
				(void) printf("Request received : \n");
				(void) print_request(&request);
			}

			request = swapmsg(request);
			process_request(&request, &response);

			if (debug) {
				(void) printf("Response sent : \n");
				print_response(&response);
			}

			/*
			 * Can block here, is this what I want?
			 */
			cc = sendto(0, (char *)&response, sizeof (response), 0,
			    (struct sockaddr *)&request.ctl_addr,
			    (socklen_t)sizeof (request.ctl_addr));

			if (cc != sizeof (response)) {
				print_error("Send");
			}
		}
	}
}
Пример #9
0
static CTL_MSG *
lookup_request (CTL_MSG * request,
		int (*comp) (table_t *, CTL_MSG *, time_t *))
{
  table_t *ptr;
  time_t now;

  time (&now);

  if (debug)
    print_request ("lookup_request", request);

  for (ptr = table; ptr; ptr = ptr->next)
    {
      if (debug)
	print_request ("comparing against: ", &ptr->request);

      if ((ptr->time - now) > max_request_ttl)
	{
	  /* the entry is too old */
	  if (debug)
	    print_request ("deleting expired entry", &ptr->request);
	  table_delete (ptr);
	}
      else
	{
	  if (comp (ptr, request, &now) == 0)
	    {
	      if (debug)
		print_request ("found", &ptr->request);
	      return &ptr->request;
	    }
	}
    }
  if (debug)
    syslog (LOG_DEBUG, "not found");
  return NULL;
}
Пример #10
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);
}
Пример #11
0
void iSLIP_schedule(int *accept,int *request,int *grant,int *ai,int *gi,int *ql,int numPort)
{
	init(accept,request,grant,numPort);
	send_request(request,ql,numPort);
#ifdef DEBUG
	print_request(request,numPort);
#endif
	do_grant(request,grant,gi,numPort);
#ifdef DEBUG
	print_grant(grant,gi,numPort);
#endif
	do_accept(accept,grant,ai,numPort);
	update_priorityPointers(grant,accept,gi,numPort);
#ifdef DEBUG
	print_accept(accept,ai,numPort);
	print_pointers(gi,numPort);
#endif
}	
Пример #12
0
void buffer_flushdat(char *hostname, int port, mxArray *plhs[], const mxArray *prhs[])
{
	int server;
    int verbose = 0;

	message_t *request  = NULL;
	message_t *response = NULL;
	header_t  *header   = NULL;

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

	/* open the TCP socket */
	if ((server = open_connection(hostname, port)) < 0) {
		mexErrMsgTxt("ERROR: failed to create socket\n");
	}

	if (verbose) print_request(request->def);
	clientrequest(server, request, &response);
	if (verbose) print_response(response->def);
	close_connection(server);

	if (response->def->command!=FLUSH_OK) {
		mexErrMsgTxt("ERROR: the buffer returned an error\n");
	}

	if (request) {
		FREE(request->def);
		FREE(request->buf);
		FREE(request);
	}
	if (response) {
		FREE(response->def);
		FREE(response->buf);
		FREE(response);
	}

	return;
}
Пример #13
0
int buffer_flushevt(int server, mxArray *plhs[], const mxArray *prhs[])
{
	int verbose = 0;
	int result;
  
	message_t *request  = NULL;
	message_t *response = NULL;

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

	if (verbose) print_request(request->def);
	result = clientrequest(server, request, &response);
	if (verbose) print_response(response->def);

	if (result == 0) {
		if (response->def->command!=FLUSH_OK) {
			result = response->def->command;
		}
	}

	if (request) {
		FREE(request->def);
		FREE(request->buf);
		FREE(request);
	}
	if (response) {
		FREE(response->def);
		FREE(response->buf);
		FREE(response);
	}

	return result;
}
Пример #14
0
int
main (int argc, char **argv)
{
    int		 retval;
    PRFileDesc	*in_file;
    FILE	*out_file;	/* not PRFileDesc until SECU accepts it */
    int		 crequest, dresponse;
    int		 prequest, presponse;
    int		 ccert, vcert;
    const char	*db_dir, *date_str, *cert_usage_str, *name;
    const char	*responder_name, *responder_url, *signer_name;
    PRBool	 add_acceptable_responses, add_service_locator;
    SECItem	*data = NULL;
    PLOptState	*optstate;
    SECStatus	 rv;
    CERTCertDBHandle *handle = NULL;
    SECCertUsage cert_usage;
    PRTime	 verify_time;
    CERTCertificate *cert = NULL;
    PRBool ascii = PR_FALSE;

    retval = -1;		/* what we return/exit with on error */

    program_name = PL_strrchr(argv[0], '/');
    program_name = program_name ? (program_name + 1) : argv[0];

    in_file = PR_STDIN;
    out_file = stdout;

    crequest = 0;
    dresponse = 0;
    prequest = 0;
    presponse = 0;
    ccert = 0;
    vcert = 0;

    db_dir = NULL;
    date_str = NULL;
    cert_usage_str = NULL;
    name = NULL;
    responder_name = NULL;
    responder_url = NULL;
    signer_name = NULL;

    add_acceptable_responses = PR_FALSE;
    add_service_locator = PR_FALSE;

    optstate = PL_CreateOptState (argc, argv, "AHLPR:S:V:d:l:pr:s:t:u:w:");
    if (optstate == NULL) {
	SECU_PrintError (program_name, "PL_CreateOptState failed");
	return retval;
    }

    while (PL_GetNextOpt (optstate) == PL_OPT_OK) {
	switch (optstate->option) {
	  case '?':
	    short_usage (program_name);
	    return retval;

	  case 'A':
	    add_acceptable_responses = PR_TRUE;
	    break;

	  case 'H':
	    long_usage (program_name);
	    return retval;

	  case 'L':
	    add_service_locator = PR_TRUE;
	    break;

	  case 'P':
	    presponse = 1;
	    break;

	  case 'R':
	    dresponse = 1;
	    name = optstate->value;
	    break;

	  case 'S':
	    ccert = 1;
	    name = optstate->value;
	    break;

	  case 'V':
	    vcert = 1;
	    name = optstate->value;
	    break;

	  case 'a':
	    ascii = PR_TRUE;
	    break;

	  case 'd':
	    db_dir = optstate->value;
	    break;

	  case 'l':
	    responder_url = optstate->value;
	    break;

	  case 'p':
	    prequest = 1;
	    break;

	  case 'r':
	    crequest = 1;
	    name = optstate->value;
	    break;

	  case 's':
	    signer_name = optstate->value;
	    break;

	  case 't':
	    responder_name = optstate->value;
	    break;

	  case 'u':
	    cert_usage_str = optstate->value;
	    break;

	  case 'w':
	    date_str = optstate->value;
	    break;
	}
    }

    PL_DestroyOptState(optstate);

    if ((crequest + dresponse + prequest + presponse + ccert + vcert) != 1) {
	PR_fprintf (PR_STDERR, "%s: must specify exactly one command\n\n",
		    program_name);
	short_usage (program_name);
	return retval;
    }

    if (vcert) {
	if (cert_usage_str == NULL) {
	    PR_fprintf (PR_STDERR, "%s: verification requires cert usage\n\n",
			program_name);
	    short_usage (program_name);
	    return retval;
	}

	rv = cert_usage_from_char (cert_usage_str, &cert_usage);
	if (rv != SECSuccess) {
	    PR_fprintf (PR_STDERR, "%s: invalid cert usage (\"%s\")\n\n",
			program_name, cert_usage_str);
	    long_usage (program_name);
	    return retval;
	}
    }

    if (ccert + vcert) {
	if (responder_url != NULL || responder_name != NULL) {
	    /*
	     * To do a full status check, both the URL and the cert name
	     * of the responder must be specified if either one is.
	     */
	    if (responder_url == NULL || responder_name == NULL) {
		if (responder_url == NULL)
		    PR_fprintf (PR_STDERR,
				"%s: must also specify responder location\n\n",
				program_name);
		else
		    PR_fprintf (PR_STDERR,
				"%s: must also specify responder name\n\n",
				program_name);
		short_usage (program_name);
		return retval;
	    }
	}

	if (date_str != NULL) {
	    rv = DER_AsciiToTime (&verify_time, (char *) date_str);
	    if (rv != SECSuccess) {
		SECU_PrintError (program_name, "error converting time string");
		PR_fprintf (PR_STDERR, "\n");
		long_usage (program_name);
		return retval;
	    }
	} else {
	    verify_time = PR_Now();
	}
    }

    retval = -2;		/* errors change from usage to runtime */

    /*
     * Initialize the NSPR and Security libraries.
     */
    PR_Init (PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
    db_dir = SECU_ConfigDirectory (db_dir);
    rv = NSS_Init (db_dir);
    if (rv != SECSuccess) {
	SECU_PrintError (program_name, "NSS_Init failed");
	goto prdone;
    }
    SECU_RegisterDynamicOids();

    if (prequest + presponse) {
	MAKE_FILE_BINARY(stdin);
	data = read_file_into_item (in_file, siBuffer);
	if (data == NULL) {
	    SECU_PrintError (program_name, "problem reading input");
	    goto nssdone;
	}
    }

    if (crequest + dresponse + presponse + ccert + vcert) {
	handle = CERT_GetDefaultCertDB();
	if (handle == NULL) {
	    SECU_PrintError (program_name, "problem getting certdb handle");
	    goto nssdone;
	}

	/*
	 * It would be fine to do the enable for all of these commands,
	 * but this way we check that everything but an overall verify
	 * can be done without it.  That is, that the individual pieces
	 * work on their own.
	 */
	if (vcert) {
	    rv = CERT_EnableOCSPChecking (handle);
	    if (rv != SECSuccess) {
		SECU_PrintError (program_name, "error enabling OCSP checking");
		goto nssdone;
	    }
	}

	if ((ccert + vcert) && (responder_name != NULL)) {
	    rv = CERT_SetOCSPDefaultResponder (handle, responder_url,
					       responder_name);
	    if (rv != SECSuccess) {
		SECU_PrintError (program_name,
				 "error setting default responder");
		goto nssdone;
	    }

	    rv = CERT_EnableOCSPDefaultResponder (handle);
	    if (rv != SECSuccess) {
		SECU_PrintError (program_name,
				 "error enabling default responder");
		goto nssdone;
	    }
	}
    }

#define NOTYET(opt)							\
	{								\
	    PR_fprintf (PR_STDERR, "%s not yet working\n", opt);	\
	    exit (-1);							\
	}

    if (name) {
        cert = find_certificate(handle, name, ascii);
    }

    if (crequest) {
	if (signer_name != NULL) {
	    NOTYET("-s");
	}
	rv = create_request (out_file, handle, cert, add_service_locator,
			     add_acceptable_responses);
    } else if (dresponse) {
	if (signer_name != NULL) {
	    NOTYET("-s");
	}
	rv = dump_response (out_file, handle, cert, responder_url);
    } else if (prequest) {
	rv = print_request (out_file, data);
    } else if (presponse) {
	rv = print_response (out_file, data, handle);
    } else if (ccert) {
	if (signer_name != NULL) {
	    NOTYET("-s");
	}
	rv = get_cert_status (out_file, handle, cert, name, verify_time);
    } else if (vcert) {
	if (signer_name != NULL) {
	    NOTYET("-s");
	}
	rv = verify_cert (out_file, handle, cert, name, cert_usage, verify_time);
    }

    if (rv != SECSuccess)
	SECU_PrintError (program_name, "error performing requested operation");
    else
	retval = 0;

nssdone:
    if (cert) {
        CERT_DestroyCertificate(cert);
    }

    if (data != NULL) {
	SECITEM_FreeItem (data, PR_TRUE);
    }

    if (handle != NULL) {
 	CERT_DisableOCSPDefaultResponder(handle);        
 	CERT_DisableOCSPChecking (handle);
    }

    if (NSS_Shutdown () != SECSuccess) {
	retval = 1;
    }

prdone:
    PR_Cleanup ();
    return retval;
}
Пример #15
0
/*
 * SOCKDGRAM is unreliable, so we must repeat messages if we have
 * not received an acknowledgement within a reasonable amount
 * of time
 */
void TalkConnection::ctl_transact(int type, int id_num)
{

    if (protocol == noProtocol)
        /** We've been so far, but we still don't know which protocol to use.
         * Let's check it, the way ktalk does. */
        findProtocol();

    fd_set read_mask, ctl_mask;
    int nready=0, cc, size, ok=0;
    struct timeval wait;
    struct sockaddr_in daemon_addr;
    char * msg;

    if (protocol == talkProtocol) {
        old_msg.type = type;
        old_msg.id_num = htonl(id_num);
        msg = (char *)&old_msg;
        size = sizeof old_msg;
    } else {
        new_msg.type = type;
        new_msg.id_num = htonl(id_num);
        msg = (char *)&new_msg;
        size = sizeof new_msg;
        print_request("ctl_transact: ",&new_msg);
    }

    daemon_addr.sin_family = AF_INET;
    daemon_addr.sin_addr = his_machine_addr;
    daemon_addr.sin_port = (protocol == talkProtocol) ? talkDaemonPort : ntalkDaemonPort;
    FD_ZERO(&ctl_mask);
    FD_SET(ctl_sockt, &ctl_mask);

    /* Keep sending the message until a response of
     * the proper type is obtained.
     */
    do {
        /* resend message until a response is obtained */
        do {
            cc = sendto(ctl_sockt, msg, size, 0,
                        (struct sockaddr *)&daemon_addr,
                        sizeof (daemon_addr));
            if (cc != size) {
                if (errno == EINTR)
                    continue;
                p_error("Error on write to talk daemon");
            }
            read_mask = ctl_mask;
            wait.tv_sec = CTL_WAIT;
            wait.tv_usec = 0;
            nready = ::select(ctl_sockt+1, &read_mask, 0, 0, &wait);
            if (nready < 0) {
                if (errno == EINTR)
                    continue;
                p_error("Error waiting for daemon response");
            }
            if (nready == 0) ktalk_debug("select returned 0 ! ");
        } while (nready == 0);
        /*
         * Keep reading while there are queued messages
         * (this is not necessary, it just saves extra
         * request/acknowledgements being sent)
         */
        do {
            if (protocol == talkProtocol)
                cc = ::recv(ctl_sockt, (char *)&old_resp, sizeof (old_resp), 0);
            else
                cc = ::recv(ctl_sockt, (char *)&new_resp, sizeof (new_resp), 0);
            if (cc < 0) {
                if (errno == EINTR)
                    continue;
                p_error("Error on read from talk daemon");
            }
            read_mask = ctl_mask;
            /* an immediate poll */
            timerclear(&wait);
            nready = ::select(ctl_sockt+1, &read_mask, 0, 0, &wait);
            if (protocol == talkProtocol) ok = (old_resp.type == type);
            else ok = ((new_resp.type == type) && (new_resp.vers == TALK_VERSION));
        } while (nready > 0 && (!ok));
    } while (!ok);
    if (protocol == talkProtocol) {
        old_resp.id_num = ntohl(old_resp.id_num);
        old_resp.addr.ta_family = ntohs(old_resp.addr.ta_family);
    } else {
        new_resp.id_num = ntohl(new_resp.id_num);
        new_resp.addr.ta_family = ntohs(new_resp.addr.ta_family);
    }
}
Пример #16
0
void buffer_getdat(char *hostname, int port, mxArray *plhs[], const mxArray *prhs[])
{
  int server;
  int verbose = 0;
  size_t n;
  double *val;
  char msg[512];
  
  message_t *request  = NULL;
  message_t *response = NULL;
  header_t  *header   = NULL;
  data_t    *data     = NULL;
  datasel_t datasel;
  
  /* this is for the Matlab specific output */
  const char *field_names[NUMBER_OF_FIELDS] = {"nchans", "nsamples", "data_type", "bufsize", "buf"};
  mxArray *datp;
  
  /* allocate the elements that will be used in the communication */
  request      = malloc(sizeof(message_t));
  request->def = malloc(sizeof(messagedef_t));
  request->buf = NULL;
  request->def->version = VERSION;
  request->def->command = GET_DAT;
  request->def->bufsize = 0;
  
  if ((prhs[0]!=NULL) && (mxGetNumberOfElements(prhs[0])==2) && (mxIsDouble(prhs[0])) && (!mxIsComplex(prhs[0]))) {
    /* fprintf(stderr, "args OK\n"); */
    val = (double *)mxGetData(prhs[0]);
    datasel.begsample = (UINT32_T)(val[0]);
    datasel.endsample = (UINT32_T)(val[1]);
    if (verbose) print_datasel(&datasel);
    request->def->bufsize = append(&request->buf, request->def->bufsize, &datasel, sizeof(datasel_t));
  }
  
  /* open the TCP socket */
  if ((server = open_connection(hostname, port)) < 0) {
    sprintf(msg, "ERROR: failed to create socket (%d)\n", server);
		mexErrMsgTxt(msg);
  }
  
  if (verbose) print_request(request->def);
  clientrequest(server, request, &response);
  if (verbose) print_response(response->def);
  close_connection(server);
  
  if (response->def->command==GET_OK) {
    data      = malloc(sizeof(data_t));
    data->def = response->buf;
    data->buf = (char *)response->buf + sizeof(datadef_t);
    if (verbose) print_datadef(data->def);
    
    switch (data->def->data_type) {
      case DATATYPE_INT8:
        datp = mxCreateNumericMatrix(data->def->nchans, data->def->nsamples, mxINT8_CLASS, mxREAL);
        memcpy(mxGetPr(datp), data->buf, data->def->nchans*data->def->nsamples*WORDSIZE_INT8);
        break;
      case DATATYPE_INT16:
        datp = mxCreateNumericMatrix(data->def->nchans, data->def->nsamples, mxINT16_CLASS, mxREAL);
        memcpy(mxGetPr(datp), data->buf, data->def->nchans*data->def->nsamples*WORDSIZE_INT16);
        break;
      case DATATYPE_INT32:
        datp = mxCreateNumericMatrix(data->def->nchans, data->def->nsamples, mxINT32_CLASS, mxREAL);
        memcpy(mxGetPr(datp), data->buf, data->def->nchans*data->def->nsamples*WORDSIZE_INT32);
        break;
      case DATATYPE_INT64:
        datp = mxCreateNumericMatrix(data->def->nchans, data->def->nsamples, mxINT64_CLASS, mxREAL);
        memcpy(mxGetPr(datp), data->buf, data->def->nchans*data->def->nsamples*WORDSIZE_INT64);
        break;
      case DATATYPE_FLOAT32:
        datp = mxCreateNumericMatrix(data->def->nchans, data->def->nsamples, mxSINGLE_CLASS, mxREAL);
        memcpy(mxGetPr(datp), data->buf, data->def->nchans*data->def->nsamples*WORDSIZE_FLOAT32);
        break;
      case DATATYPE_FLOAT64:
        datp = mxCreateNumericMatrix(data->def->nchans, data->def->nsamples, mxDOUBLE_CLASS, mxREAL);
        memcpy(mxGetPr(datp), data->buf, data->def->nchans*data->def->nsamples*WORDSIZE_FLOAT64);
        break;
        default:
          mexErrMsgTxt("ERROR; unsupported data type\n");
    }
    
    plhs[0] = mxCreateStructMatrix(1, 1, NUMBER_OF_FIELDS, field_names);
    mxSetFieldByNumber(plhs[0], 0, 0, mxCreateDoubleScalar((double)data->def->nchans));
    mxSetFieldByNumber(plhs[0], 0, 1, mxCreateDoubleScalar((double)(data->def->nsamples)));
    mxSetFieldByNumber(plhs[0], 0, 2, mxCreateDoubleScalar((double)(data->def->data_type)));
    mxSetFieldByNumber(plhs[0], 0, 3, mxCreateDoubleScalar((double)(data->def->bufsize)));
    mxSetFieldByNumber(plhs[0], 0, 4, datp);
    FREE(data);
  }
  else {
    sprintf(msg, "ERROR: the buffer returned an error (%d)\n", response->def->command);
		mexErrMsgTxt(msg);
  }
  
  if (request) {
    FREE(request->def);
    FREE(request->buf);
    FREE(request);
  }
  if (response) {
    FREE(response->def);
    FREE(response->buf);
    FREE(response);
  }
  
  return;
}
Пример #17
0
void
process_request(CTL_MSG *mp, CTL_RESPONSE *rp)
{
	CTL_MSG *ptr;
	char *s;

	rp->vers = TALK_VERSION;
	rp->type = mp->type;
	rp->id_num = htonl(0);
	if (mp->vers != TALK_VERSION) {
		syslog(LOG_WARNING, "bad protocol version %d", mp->vers);
		rp->answer = BADVERSION;
		return;
	}
	mp->id_num = ntohl(mp->id_num);
	mp->addr.sa_family = ntohs(mp->addr.sa_family);
	if (mp->addr.sa_family != AF_INET) {
		syslog(LOG_WARNING, "bad address, family %d",
		    mp->addr.sa_family);
		rp->answer = BADADDR;
		return;
	}
	mp->ctl_addr.sa_family = ntohs(mp->ctl_addr.sa_family);
	if (mp->ctl_addr.sa_family != AF_INET) {
		syslog(LOG_WARNING, "bad control address, family %d",
		    mp->ctl_addr.sa_family);
		rp->answer = BADCTLADDR;
		return;
	}
	for (s = mp->l_name; *s; s++)
		if (!isprint(*s)) {
			syslog(LOG_NOTICE, "illegal user name. Aborting");
			rp->answer = FAILED;
			return;
		}
	mp->pid = ntohl(mp->pid);
	if (debug)
		print_request("process_request", mp);
	switch (mp->type) {

	case ANNOUNCE:
		do_announce(mp, rp);
		break;

	case LEAVE_INVITE:
		ptr = find_request(mp);
		if (ptr != NULL) {
			rp->id_num = htonl(ptr->id_num);
			rp->answer = SUCCESS;
		} else
			insert_table(mp, rp);
		break;

	case LOOK_UP:
		ptr = find_match(mp);
		if (ptr != NULL) {
			rp->id_num = htonl(ptr->id_num);
			rp->addr = ptr->addr;
			rp->addr.sa_family = htons(ptr->addr.sa_family);
			rp->answer = SUCCESS;
		} else
			rp->answer = NOT_HERE;
		break;

	case DELETE:
		rp->answer = delete_invite(mp->id_num);
		break;

	default:
		rp->answer = UNKNOWN_REQUEST;
		break;
	}
	if (debug)
		print_response("process_request", rp);
}
Пример #18
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;
}
Пример #19
0
int main(void)
{
    /* enable interrupts (on the CPU) */
    init_interrupts();

    /* Initialize peripherals */
    display_init( res, bit, 2, GAMMA_NONE, ANTIALIAS_RESAMPLE );
    console_init();
    controller_init();

    console_set_render_mode(RENDER_MANUAL);

    /* Main loop test */
    while(1) 
    {
        console_clear();

        /* To do initialize routines */
        controller_scan();

        int controllers = get_controllers_present();

        if( controllers & CONTROLLER_1_INSERTED )
        {
            int accessories = get_accessories_present();

            if( (accessories & CONTROLLER_4_INSERTED) && identify_accessory( 3 ) == ACCESSORY_VRU )
            {
                uint8_t out[64];
                uint8_t in[64];

                // Initial sequence
                out[0] = 0x00;
                out[1] = 0x00;
                print_request( 2, out );
                execute_raw_command( 3, 0xB, 2, 3, out, in );
                print_result( 3, in );

                // LODS OF 0x0B
                out[0] = 0x1E;
                out[1] = 0x0C;
                print_request( 2, out );
                execute_raw_command( 3, 0xD, 2, 1, out, in );
                print_result( 1, in );

                out[0] = 0x6E;
                out[1] = 0x07;
                print_request( 2, out );
                execute_raw_command( 3, 0xD, 2, 1, out, in );
                print_result( 1, in );

                out[0] = 0x08;
                out[1] = 0x0E;
                print_request( 2, out );
                execute_raw_command( 3, 0xD, 2, 1, out, in );
                print_result( 1, in );

                out[0] = 0x56;
                out[1] = 0x18;
                print_request( 2, out );
                execute_raw_command( 3, 0xD, 2, 1, out, in );
                print_result( 1, in );

                out[0] = 0x03;
                out[1] = 0x0F;
                print_request( 2, out );
                execute_raw_command( 3, 0xD, 2, 1, out, in );
                print_result( 1, in );

                // Some C's and B's
                out[0] = 0x00;
                out[1] = 0x00;
                out[2] = 0x00;
                out[3] = 0x00;
                out[4] = 0x01;
                out[5] = 0x00;
                print_request( 6, out );
                execute_raw_command( 3, 0xC, 6, 1, out, in );
                print_result( 1, in );

                out[0] = 0x00;
                out[1] = 0x00;
                print_request( 2, out );
                execute_raw_command( 3, 0xB, 2, 3, out, in );
                print_result( 3, in );
                
                out[0] = 0x00;
                out[1] = 0x00;
                out[2] = 0x02;
                out[3] = 0x00;
                out[4] = 0x3B;
                out[5] = 0x00;
                print_request( 6, out );
                execute_raw_command( 3, 0xC, 6, 1, out, in );
                print_result( 1, in );

                out[0] = 0x00;
                out[1] = 0x00;
                print_request( 2, out );
                execute_raw_command( 3, 0xB, 2, 3, out, in );
                print_result( 3, in );

                // Give that A a try
                memset( out, 0, sizeof( out ) );
                print_request( 22, out );
                execute_raw_command( 3, 0xA, 22, 1, out, in );
                print_result( 1, in );

                memset( out, 0, sizeof( out ) );
                print_request( 22, out );
                execute_raw_command( 3, 0xA, 22, 1, out, in );
                print_result( 1, in );

                memset( out, 0, sizeof( out ) );
                out[14] = 0x03;
                out[18] = 0x12;
                out[20] = 0x08;
                print_request( 22, out );
                execute_raw_command( 3, 0xA, 22, 1, out, in );
                print_result( 1, in );

                // Render it!
                console_render();
                while(1){;}
            }
            else
            {
                printf( "Please insert a VRU into slot 4.\n" );
            }
        }
        else
        {
            printf( "Please insert a standard\ncontroller into slot 1.\n" );
        }

        console_render();
    }
}
Пример #20
0
void
process_request(CTL_MSG *mp, CTL_RESPONSE *rp)
{
	CTL_MSG *ptr;
	char *s;

	rp->vers = TALK_VERSION;
	rp->type = mp->type;
	rp->id_num = htonl(0);
	if (mp->vers != TALK_VERSION) {
		syslog(LOG_WARNING, "Bad protocol version %d", mp->vers);
		rp->answer = BADVERSION;
		return;
	}
	mp->id_num = ntohl(mp->id_num);
	if (ntohs(mp->addr.sa_family) != AF_INET) {
		syslog(LOG_WARNING, "Bad address, family %d",
		    ntohs(mp->addr.sa_family));
		rp->answer = BADADDR;
		return;
	}
	if (ntohs(mp->ctl_addr.sa_family) != AF_INET) {
		syslog(LOG_WARNING, "Bad control address, family %d",
		    ntohs(mp->ctl_addr.sa_family));
		rp->answer = BADCTLADDR;
		return;
	}
	for (s = mp->l_name; *s; s++)
		if (!isprint((unsigned char)*s)) {
			syslog(LOG_NOTICE, "Illegal user name. Aborting");
			rp->answer = FAILED;
			return;
		}
	if (memcmp(&satosin(&rp->addr)->sin_addr,
	    &satosin(&mp->ctl_addr)->sin_addr,
	    sizeof(struct in_addr))) {
		char buf1[32], buf2[32];

		strlcpy(buf1, inet_ntoa(satosin(&rp->addr)->sin_addr),
		    sizeof(buf1));
		strlcpy(buf2, inet_ntoa(satosin(&mp->ctl_addr)->sin_addr),
		    sizeof(buf2));
		syslog(LOG_WARNING, "addresses are different, %s != %s",
		    buf1, buf2);
	}
	rp->addr.sa_family = 0;
	mp->pid = ntohl(mp->pid);
	if (debug)
		print_request("process_request", mp);
	switch (mp->type) {

	case ANNOUNCE:
		do_announce(mp, rp);
		break;

	case LEAVE_INVITE:
		ptr = find_request(mp);
		if (ptr != (CTL_MSG *)0) {
			rp->id_num = htonl(ptr->id_num);
			rp->answer = SUCCESS;
		} else
			insert_table(mp, rp);
		break;

	case LOOK_UP:
		ptr = find_match(mp);
		if (ptr != (CTL_MSG *)0) {
			rp->id_num = htonl(ptr->id_num);
			rp->addr = ptr->addr;
			rp->addr.sa_family = ptr->addr.sa_family;
			rp->answer = SUCCESS;
		} else
			rp->answer = NOT_HERE;
		break;

	case DELETE:
		rp->answer = delete_invite(mp->id_num);
		break;

	default:
		rp->answer = UNKNOWN_REQUEST;
		break;
	}
	if (debug)
		print_response("process_request", rp);
}
Пример #21
0
/***************************************************************************** 
 * this function handles the direct memory access to the buffer
 * and copies objects to and from memory
 *****************************************************************************/
int dmarequest(const message_t *request, message_t **response_ptr) {
  unsigned int offset;
  /*
     int blockrequest = 0;
     */
  int verbose = 0;

  /* these are used for blocking the read requests */
  struct timeval tp;
  struct timespec ts;

  /* use a local variable for datasel (in GET_DAT) */
  datasel_t datasel;

  /* these are for typecasting */
  headerdef_t    *headerdef;
  datadef_t      *datadef;
  eventdef_t     *eventdef;
  eventsel_t     *eventsel;

  /* this will hold the response */
  message_t *response;
  response      = (message_t*)malloc(sizeof(message_t));

  /* check for "out of memory" problems */
  if (response == NULL) {
    *response_ptr = NULL;
    return -1;
  }
  response->def = (messagedef_t*)malloc(sizeof(messagedef_t));

  /* check for "out of memory" problems */
  if (response->def == NULL) {
    *response_ptr = NULL;
    free(response);
    return -1;
  }
  response->buf = NULL;
  /* the response should be passed to the calling function, where it should be freed */
  *response_ptr = response;

  if (verbose>1) print_request(request->def);

  switch (request->def->command) {

    case PUT_HDR:
      if (verbose>1) fprintf(stderr, "dmarequest: PUT_HDR\n");
      pthread_mutex_lock(&mutexheader);
      pthread_mutex_lock(&mutexdata);
      pthread_mutex_lock(&mutexevent);

      headerdef = (headerdef_t*)request->buf;
      if (verbose>1) print_headerdef(headerdef);

      /* delete the old header, data and events */
      free_header();
      free_data();
      free_event();

      /* store the header and re-initialize */
      header      = (header_t*)malloc(sizeof(header_t));
      DIE_BAD_MALLOC(header);
      header->def = (headerdef_t*)malloc(sizeof(headerdef_t));
      DIE_BAD_MALLOC(header->def);
      header->buf = malloc(headerdef->bufsize);
      DIE_BAD_MALLOC(header->buf);
      memcpy(header->def, request->buf, sizeof(headerdef_t));
      memcpy(header->buf, (char*)request->buf+sizeof(headerdef_t), headerdef->bufsize);
      header->def->nsamples = 0;
      header->def->nevents  = 0;

      init_data();
      init_event();

      response->def->version = VERSION;
      response->def->bufsize = 0;
      /* check whether memory could indeed be allocated */
      if (data!= NULL && data->buf != NULL && data->def != NULL) {
        response->def->command = PUT_OK;
      } else {
        /* let's at least tell the client that something's wrong */
        response->def->command = PUT_ERR;	
      }

      pthread_mutex_unlock(&mutexevent);
      pthread_mutex_unlock(&mutexdata);
      pthread_mutex_unlock(&mutexheader);
      break;

    case PUT_DAT:
      if (verbose>1) fprintf(stderr, "dmarequest: PUT_DAT\n");
      pthread_mutex_lock(&mutexheader);
      pthread_mutex_lock(&mutexdata);

      datadef = (datadef_t*)request->buf;
      if (verbose>1) print_datadef(datadef);
      if (verbose>2) print_buf(request->buf, request->def->bufsize);

      response->def->version = VERSION;
      response->def->bufsize = 0;
      if (request->def->bufsize < sizeof(datadef_t))
        response->def->command = PUT_ERR;
      else if (header==NULL || data==NULL)
        response->def->command = PUT_ERR;
      else if (header->def->nchans != datadef->nchans)
        response->def->command = PUT_ERR;
      else if (header->def->data_type != datadef->data_type)
        response->def->command = PUT_ERR;
      else if (datadef->nsamples > current_max_num_sample)
        response->def->command = PUT_ERR;
      else {
        unsigned int i;
        unsigned int wordsize = wordsize_from_type(header->def->data_type);
        unsigned int datasize = wordsize * datadef->nsamples * datadef->nchans;

        response->def->command = PUT_OK;

        if (wordsize == 0) {
          fprintf(stderr, "dmarequest: unsupported data type (%d)\n", datadef->data_type);
          response->def->command = PUT_ERR;
        } else if (datasize > datadef->bufsize || (datadef->bufsize + sizeof(datadef_t)) > request->def->bufsize) {
          fprintf(stderr, "dmarequest: invalid size definitions in PUT_DAT request\n");
          response->def->command = PUT_ERR;
        } else {

          /* record the time at which the data was received */
          if (clock_gettime(CLOCK_REALTIME, &putdat_clock) != 0) {
            perror("clock_gettime");
            return -1;
          }

          /* number of bytes per sample (all channels) is given by wordsize x number of channels */
          unsigned int chansize = wordsize * data->def->nchans;
          /* request_data points to actual data samples within the request, use char* for convenience */
          const char *request_data = (const char *) request->buf + sizeof(datadef_t);
          char *buffer_data = (char *)data->buf;

          for (i=0; i<datadef->nsamples; i++) {
            memcpy(buffer_data+(thissample*chansize), request_data+(i*chansize), chansize);
            header->def->nsamples++;
            thissample++;
            thissample = WRAP(thissample, current_max_num_sample);
          }
          /* Signal possibly waiting threads that we have received data */
          pthread_cond_broadcast(&getData_cond);
        }
      }

      pthread_mutex_unlock(&mutexdata);
      pthread_mutex_unlock(&mutexheader);
      break;

    case PUT_EVT:
      if (verbose>1) fprintf(stderr, "dmarequest: PUT_EVT\n");
      pthread_mutex_lock(&mutexheader);
      pthread_mutex_lock(&mutexevent);

      /* record the time at which the event was received */
      if (clock_gettime(CLOCK_REALTIME, &putevt_clock) != 0) {
        perror("clock_gettime");
        return -1;
      }

      /* Give an error message if there is no header, or if the given event array is defined badly */
      if (header==NULL || event==NULL || check_event_array(request->def->bufsize, request->buf) < 0) {
        response->def->version = VERSION;
        response->def->command = PUT_ERR;
        response->def->bufsize = 0;
      }
      else {	/* go over all events and store them one by one */
        response->def->version = VERSION;
        response->def->command = PUT_OK;
        response->def->bufsize = 0;

        offset = 0; /* this represents the offset of the event in the buffer */
        while (offset<request->def->bufsize) {
          FREE(event[thisevent].def);
          FREE(event[thisevent].buf);

          eventdef = (eventdef_t*)((char*)request->buf+offset);
          if (verbose>1) print_eventdef(eventdef);

          event[thisevent].def = (eventdef_t*)malloc(sizeof(eventdef_t));
          DIE_BAD_MALLOC(event[thisevent].def);
          memcpy(event[thisevent].def, (char*)request->buf+offset, sizeof(eventdef_t));

          if (event[thisevent].def->sample == EVENT_AUTO_SAMPLE) {
            /* automatically convert event->def->sample to current sample number */
            /* make some fine adjustment of the assigned sample number */
            double adjust = (putevt_clock.tv_sec - putdat_clock.tv_sec) + (double)(putevt_clock.tv_nsec - putdat_clock.tv_nsec) / 1000000000L;
            event[thisevent].def->sample = header->def->nsamples + (int)(header->def->fsample*adjust);
          }

          offset += sizeof(eventdef_t);
          event[thisevent].buf = malloc(eventdef->bufsize);
          DIE_BAD_MALLOC(event[thisevent].buf);
          memcpy(event[thisevent].buf, (char*)request->buf+offset, eventdef->bufsize);
          offset += eventdef->bufsize;
          if (verbose>1) print_eventdef(event[thisevent].def);
          thisevent++;
          thisevent = WRAP(thisevent, MAXNUMEVENT);
          header->def->nevents++;
        }
      }

      pthread_mutex_unlock(&mutexevent);
      pthread_mutex_unlock(&mutexheader);
      break;

    case GET_HDR:
      if (verbose>1) fprintf(stderr, "dmarequest: GET_HDR\n");
      if (header==NULL) {
        response->def->version = VERSION;
        response->def->command = GET_ERR;
        response->def->bufsize = 0;
        break;
      }

      pthread_mutex_lock(&mutexheader);

      response->def->version = VERSION;
      response->def->command = GET_OK;
      response->def->bufsize = 0;
      response->def->bufsize = append(&response->buf, response->def->bufsize, header->def, sizeof(headerdef_t));
      response->def->bufsize = append(&response->buf, response->def->bufsize, header->buf, header->def->bufsize);

      pthread_mutex_unlock(&mutexheader);
      break;

    case GET_DAT:
      if (verbose>1) fprintf(stderr, "dmarequest: GET_DAT\n");
      if (header==NULL || data==NULL) {
        response->def->version = VERSION;
        response->def->command = GET_ERR;
        response->def->bufsize = 0;
        break;
      }

      pthread_mutex_lock(&mutexheader);
      pthread_mutex_lock(&mutexdata);

      if (request->def->bufsize) {
        /* the selection has been specified */
        memcpy(&datasel, request->buf, sizeof(datasel_t));
        /* If endsample is -1 read the buffer to the end */
        if(datasel.endsample == -1)
        {
          datasel.endsample = header->def->nsamples - 1;
        }
      }
      else {
        /* determine a valid selection */
        if (header->def->nsamples>current_max_num_sample) {
          /* the ringbuffer is completely full */
          datasel.begsample = header->def->nsamples - current_max_num_sample;
          datasel.endsample = header->def->nsamples - 1;
        }
        else {
          /* the ringbuffer is not yet completely full */
          datasel.begsample = 0;
          datasel.endsample = header->def->nsamples - 1;
        }
      }

      /*

      // if the read should block...
      if(blockrequest == 1)
      {
      // check whether data is available
      while((datasel.begsample >= (datasel.endsample+1)) || (datasel.endsample > header->def->nsamples - 1))
      {
      // if not unlock all mutexes
      pthread_mutex_unlock(&mutexdata);
      pthread_mutex_unlock(&mutexheader);

      // wait for the condition to be signaled
      pthread_mutex_lock(&getData_mutex);
      gettimeofday(&tp, NULL);
      ts.tv_sec = tp.tv_sec;
      ts.tv_nsec = tp.tv_usec * 1000;
      ts.tv_sec += 1;
      pthread_cond_timedwait(&getData_cond, &getData_mutex, &ts);
      pthread_mutex_unlock(&getData_mutex);

      // Lock the mutexes again
      pthread_mutex_lock(&mutexheader);
      pthread_mutex_lock(&mutexdata);
      if(datasel.begsample == (datasel.endsample+1))
      datasel.endsample = header->def->nsamples - 1;
      }
      }
      */

      if (verbose>1) print_headerdef(header->def);
      if (verbose>1) print_datasel(&datasel);

      if (datasel.begsample < 0 || datasel.endsample < 0) {
        fprintf(stderr, "dmarequest: err1\n");
        response->def->version = VERSION;
        response->def->command = GET_ERR;
        response->def->bufsize = 0;
      }
      else if (datasel.begsample >= header->def->nsamples || datasel.endsample >= header->def->nsamples) {
        fprintf(stderr, "dmarequest: err2\n");
        response->def->version = VERSION;
        response->def->command = GET_ERR;
        response->def->bufsize = 0;
      }
      else if ((header->def->nsamples - datasel.begsample) > current_max_num_sample) {
        fprintf(stderr, "dmarequest: err3\n");
        response->def->version = VERSION;
        response->def->command = GET_ERR;
        response->def->bufsize = 0;
      }
      else {
        unsigned int wordsize = wordsize_from_type(data->def->data_type);
        if (wordsize==0) {
          fprintf(stderr, "dmarequest: unsupported data type (%d)\n", data->def->data_type);
          response->def->version = VERSION;
          response->def->command = GET_ERR;
          response->def->bufsize = 0;
        }  else {
          unsigned int n;
          response->def->version = VERSION;
          response->def->command = GET_OK;
          response->def->bufsize = 0;

          /* determine the number of samples to return */
          n = datasel.endsample - datasel.begsample + 1;

          response->buf = malloc(sizeof(datadef_t) + n*data->def->nchans*wordsize);
          if (response->buf == NULL) {
            /* not enough space for copying data into response */
            fprintf(stderr, "dmarequest: out of memory\n");
            response->def->command = GET_ERR;
          } 
          else {
            /* number of bytes per sample (all channels) */
            unsigned int chansize = data->def->nchans * wordsize;

            /* convenience pointer to start of actual data in response */
            char *resp_data = ((char *) response->buf) + sizeof(datadef_t);

            /* this is the location of begsample within the ringbuffer */
            unsigned int start_index = 	WRAP(datasel.begsample, current_max_num_sample);

            /* have datadef point into the freshly allocated response buffer and directly
               fill in the information */
            datadef = (datadef_t *) response->buf;
            datadef->nchans    = data->def->nchans;
            datadef->data_type = data->def->data_type;
            datadef->nsamples  = n;
            datadef->bufsize   = n*chansize;

            response->def->bufsize = sizeof(datadef_t) + datadef->bufsize;

            if (start_index + n <= current_max_num_sample) {
              /* we can copy everything in one go */
              memcpy(resp_data, (char*)(data->buf) + start_index*chansize, n*chansize);
            } else {
              /* need to wrap around at current_max_num_sample */
              unsigned int na = current_max_num_sample - start_index;
              unsigned int nb = n - na;

              memcpy(resp_data, (char*)(data->buf) + start_index*chansize, na*chansize);
              memcpy(resp_data + na*chansize, (char*)(data->buf), nb*chansize);

              /* printf("Wrapped around!\n"); */
            }
          }
        }
      }

      pthread_mutex_unlock(&mutexdata);
      pthread_mutex_unlock(&mutexheader);
      break;

    case GET_EVT:
      if (verbose>1) fprintf(stderr, "dmarequest: GET_EVT\n");
      if (header==NULL || event==NULL || header->def->nevents==0) {
        response->def->version = VERSION;
        response->def->command = GET_ERR;
        response->def->bufsize = 0;
        break;
      }

      pthread_mutex_lock(&mutexheader);
      pthread_mutex_lock(&mutexevent);

      eventsel = (eventsel_t*)malloc(sizeof(eventsel_t));
      DIE_BAD_MALLOC(eventsel);

      /* determine the selection */
      if (request->def->bufsize) {
        /* the selection has been specified */
        memcpy(eventsel, request->buf, sizeof(eventsel_t));
      }
      else {
        /* determine a valid selection */
        if (header->def->nevents>MAXNUMEVENT) {
          /* the ringbuffer is completely full */
          eventsel->begevent = header->def->nevents - MAXNUMEVENT;
          eventsel->endevent = header->def->nevents - 1;
        }
        else {
          /* the ringbuffer is not yet completely full */
          eventsel->begevent = 0;
          eventsel->endevent = header->def->nevents - 1;
        }
      }

      if (verbose>1) print_headerdef(header->def);
      if (verbose>1) print_eventsel(eventsel);

      if (eventsel==NULL) {
        response->def->version = VERSION;
        response->def->command = GET_ERR;
        response->def->bufsize = 0;
      }
      else if (eventsel->begevent < 0 || eventsel->endevent < 0) {
        fprintf(stderr, "dmarequest: err1\n");
        response->def->version = VERSION;
        response->def->command = GET_ERR;
        response->def->bufsize = 0;
      }
      else if (eventsel->begevent >= header->def->nevents || eventsel->endevent >= header->def->nevents) {
        fprintf(stderr, "dmarequest: err2\n");
        response->def->version = VERSION;
        response->def->command = GET_ERR;
        response->def->bufsize = 0;
      }
      else if ((header->def->nevents-eventsel->begevent) > MAXNUMEVENT) {
        fprintf(stderr, "dmarequest: err3\n");
        response->def->version = VERSION;
        response->def->command = GET_ERR;
        response->def->bufsize = 0;
      }
      else {
        unsigned int j,n;

        response->def->version = VERSION;
        response->def->command = GET_OK;
        response->def->bufsize = 0;

        /* determine the number of events to return */
        n = eventsel->endevent - eventsel->begevent + 1;

        for (j=0; j<n; j++) {
          if (verbose>1) print_eventdef(event[WRAP(eventsel->begevent+j, MAXNUMEVENT)].def);
          response->def->bufsize = append(&response->buf, response->def->bufsize, event[WRAP(eventsel->begevent+j, MAXNUMEVENT)].def, sizeof(eventdef_t));
          response->def->bufsize = append(&response->buf, response->def->bufsize, event[WRAP(eventsel->begevent+j, MAXNUMEVENT)].buf, event[WRAP(eventsel->begevent+j, MAXNUMEVENT)].def->bufsize);
        }
      }

      FREE(eventsel);
      pthread_mutex_unlock(&mutexevent);
      pthread_mutex_unlock(&mutexheader);
      break;

    case FLUSH_HDR:
      pthread_mutex_lock(&mutexheader);
      pthread_mutex_lock(&mutexdata);
      pthread_mutex_lock(&mutexevent);
      if (header) {
        free_header();
        free_data();
        free_event();
        response->def->version = VERSION;
        response->def->command = FLUSH_OK;
        response->def->bufsize = 0;
      }
      else {
        response->def->version = VERSION;
        response->def->command = FLUSH_ERR;
        response->def->bufsize = 0;
      }
      pthread_mutex_unlock(&mutexevent);
      pthread_mutex_unlock(&mutexdata);
      pthread_mutex_unlock(&mutexheader);
      break;

    case FLUSH_DAT:
      pthread_mutex_lock(&mutexheader);
      pthread_mutex_lock(&mutexdata);
      if (header && data) {
        header->def->nsamples = thissample = 0;
        response->def->version = VERSION;
        response->def->command = FLUSH_OK;
        response->def->bufsize = 0;
      }
      else {
        response->def->version = VERSION;
        response->def->command = FLUSH_ERR;
        response->def->bufsize = 0;
      }
      pthread_mutex_unlock(&mutexdata);
      pthread_mutex_unlock(&mutexheader);
      break;

    case FLUSH_EVT:
      pthread_mutex_lock(&mutexheader);
      pthread_mutex_lock(&mutexevent);
      if (header && event) {
        unsigned int i;

        header->def->nevents = thisevent = 0;
        for (i=0; i<MAXNUMEVENT; i++) {
          FREE(event[i].def);
          FREE(event[i].buf);
        }
        response->def->version = VERSION;
        response->def->command = FLUSH_OK;
        response->def->bufsize = 0;
      }
      else {
        response->def->version = VERSION;
        response->def->command = FLUSH_ERR;
        response->def->bufsize = 0;
      }
      pthread_mutex_unlock(&mutexevent);
      pthread_mutex_unlock(&mutexheader);
      break;

    case WAIT_DAT:
      /* SK: This request means that the client wants to wait until
         MORE than waitdef_t.threshold.nsamples samples OR 
         MORE THAN waitdef_t.threshold.nevents events 
         are in the buffer, BUT 
         only for the time given in waitdef_t.milliseconds. 
         The response is just the number of samples and events 
         in the buffer as described by samples_events_t.
         */
      response->def->version = VERSION;
      if (header==NULL || request->def->bufsize!=sizeof(waitdef_t)) {
        response->def->command = WAIT_ERR;
        response->def->bufsize = 0;
      } else {
        int waiterr;
        waitdef_t *wd = (waitdef_t *) request->buf;
        samples_events_t *nret = malloc(sizeof(samples_events_t));
        UINT32_T nsmp, nevt;

        if (nret == NULL) {
          /* highly unlikely, but we cannot allocate a sample_event_t - return an error */
          response->def->command = WAIT_ERR;
          response->def->bufsize = 0;
          break;
        }
        /* Let response->buf point to the new sample_event_t structure */
        response->def->command = WAIT_OK;
        response->def->bufsize = sizeof(samples_events_t);
        response->buf = nret;

        /* get current number of samples */
        pthread_mutex_lock(&mutexheader);
        nsmp = header->def->nsamples;
        nevt = header->def->nevents;
        pthread_mutex_unlock(&mutexheader);

        if (wd->milliseconds == 0 || nsmp > wd->threshold.nsamples || nevt > wd->threshold.nevents) {
          /* the client doesn't want to wait, or
             we're already above the threshold: 
             return immediately */
          nret->nsamples = nsmp;
          nret->nevents = nevt;
          break;
        }
        gettimeofday(&tp, NULL);
        ts.tv_sec = tp.tv_sec + (wd->milliseconds/1000);
        ts.tv_nsec = 1000 * (tp.tv_usec + (wd->milliseconds % 1000)*1000);
        while (ts.tv_nsec >= 1000000000) {
          ts.tv_sec++;
          ts.tv_nsec-=1000000000;
        }

        /* FIXME: The getData condition variable is only triggered by incoming data, not events */
        do {
          pthread_mutex_lock(&getData_mutex);
          waiterr = pthread_cond_timedwait(&getData_cond, &getData_mutex, &ts);
          pthread_mutex_unlock(&getData_mutex);

          /* get current number of samples */
          pthread_mutex_lock(&mutexheader);
          nsmp = header->def->nsamples;
          nevt = header->def->nevents;
          pthread_mutex_unlock(&mutexheader);
        } while (nsmp <= wd->threshold.nsamples && nevt <= wd->threshold.nevents && waiterr==0);
        nret->nsamples = nsmp;
        nret->nevents = nevt;				
      }
      break;
    default:
      fprintf(stderr, "dmarequest: unknown command\n");
  }

  if (verbose>0) fprintf(stderr, "dmarequest: thissample = %u, thisevent = %u\n", thissample, thisevent);

  /* everything went fine */
  return 0;
}
Пример #22
0
int
process_request (CTL_MSG * msg, struct sockaddr_in *sa_in, CTL_RESPONSE * rp)
{
  CTL_MSG *ptr;

  if (debug)
    {
      print_request ("process_request", msg);
    }

  if (acl_match (msg, sa_in))
    {
      syslog (LOG_NOTICE, "dropping request: %s@%s",
	      msg->l_name, inet_ntoa (sa_in->sin_addr));
      return 1;
    }

  rp->vers = TALK_VERSION;
  rp->type = msg->type;
  rp->id_num = htonl (0);
  if (msg->vers != TALK_VERSION)
    {
      syslog (LOG_ERR, "Bad protocol version %d", msg->vers);
      rp->answer = BADVERSION;
      return 0;
    }

  msg->id_num = ntohl (msg->id_num);
  msg->addr.sa_family = ntohs (msg->addr.sa_family);
  if (msg->addr.sa_family != AF_INET)
    {
      syslog (LOG_ERR, "Bad address, family %d", msg->addr.sa_family);
      rp->answer = BADADDR;
      return 0;
    }
  msg->ctl_addr.sa_family = ntohs (msg->ctl_addr.sa_family);
  if (msg->ctl_addr.sa_family != AF_INET)
    {
      syslog (LOG_WARNING, "Bad control address, family %d",
	      msg->ctl_addr.sa_family);
      rp->answer = BADCTLADDR;
      return 0;
    }
  /* FIXME: compare address and sa_in? */

  msg->pid = ntohl (msg->pid);

  switch (msg->type)
    {
    case ANNOUNCE:
      do_announce (msg, rp);
      break;

    case LEAVE_INVITE:
      ptr = find_request (msg);
      if (ptr)
	{
	  rp->id_num = htonl (ptr->id_num);
	  rp->answer = SUCCESS;
	}
      else
	insert_table (msg, rp);
      break;

    case LOOK_UP:
      ptr = find_match (msg);
      if (ptr)
	{
	  rp->id_num = htonl (ptr->id_num);
	  rp->addr = ptr->addr;
	  rp->addr.sa_family = htons (ptr->addr.sa_family);
	  rp->answer = SUCCESS;
	}
      else
	rp->answer = NOT_HERE;
      break;

    case DELETE:
      rp->answer = delete_invite (msg->id_num);
      break;

    default:
      rp->answer = UNKNOWN_REQUEST;
      break;
    }

  if (debug)
    print_response ("process_request response", rp);

  return 0;
}
Пример #23
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;
}
Пример #24
0
int buffer_getevt(int server, mxArray *plhs[], const mxArray *prhs[])
{
  int verbose = 0;
  int i, nevents;
  int offset;
  double *val;
  int result;
  
  mxArray *bufptr;
  
  
  message_t *request  = NULL;
  message_t *response = NULL;
  eventsel_t eventsel;
  
  /* this is for the Matlab specific output */
  const char *field_names[] = {
    "type",
    "value",
    "sample",
    "offset",
    "duration"
  };
  
  /* allocate the elements that will be used in the communication */
  request      = malloc(sizeof(message_t));
  request->def = malloc(sizeof(messagedef_t));
  request->buf = NULL;
  request->def->version = VERSION;
  request->def->command = GET_EVT;
  request->def->bufsize = 0;
  
  if ((prhs[0]!=NULL) && (mxGetNumberOfElements(prhs[0])==2) && (mxIsDouble(prhs[0])) && (!mxIsComplex(prhs[0]))) {
    /* fprintf(stderr, "args OK\n"); */
    val = (double *)mxGetData(prhs[0]);
    eventsel.begevent = (UINT32_T)(val[0]);
    eventsel.endevent = (UINT32_T)(val[1]);
    if (verbose) print_eventsel(&eventsel);
    request->def->bufsize = append(&request->buf, request->def->bufsize, &eventsel, sizeof(eventsel_t));
  }
  
  if (verbose) print_request(request->def);
  result = clientrequest(server, request, &response);
  if (verbose) print_response(response->def);
  
  if (result == 0) {
    if (response->def->command==GET_OK) {
	  eventdef_t *event_def;
      /* first count the number of events */
      nevents = 0;
      offset = 0;
      while (offset<response->def->bufsize) {
        event_def = (eventdef_t *)((char *)response->buf + offset);
        /* event_buf = (char *)response->buf + offset + sizeof(eventdef_t); */
        if (verbose) print_eventdef(event_def);
        offset += sizeof(eventdef_t) + event_def->bufsize;
        nevents++;
      }
      
      /* create a structure array that can hold all events */
      plhs[0] = mxCreateStructMatrix(1, nevents, NUMBER_OF_FIELDS, field_names);
      
      offset = 0;
      for (i=0; i<nevents; i++) {
	  	char *buf_type,*buf_value;
		
        event_def = (eventdef_t *) ((char *)response->buf + offset);
		buf_type = (char *) response->buf + offset + sizeof(eventdef_t);
		buf_value = buf_type + event_def->type_numel * wordsize_from_type(event_def->type_type);
                
		mxSetFieldByNumber(plhs[0], i, 0, matrix_from_ft_type_data(event_def->type_type, 1, event_def->type_numel, buf_type));
		mxSetFieldByNumber(plhs[0], i, 1, matrix_from_ft_type_data(event_def->value_type, 1, event_def->value_numel, buf_value));
        mxSetFieldByNumber(plhs[0], i, 2, mxCreateDoubleScalar((double)event_def->sample+1)); /* 1-based in Matlab, 0-based in protocol */
        mxSetFieldByNumber(plhs[0], i, 3, mxCreateDoubleScalar((double)event_def->offset));
        mxSetFieldByNumber(plhs[0], i, 4, mxCreateDoubleScalar((double)event_def->duration));
        offset += sizeof(eventdef_t) + event_def->bufsize;
      }
    }
    else {
      result = response->def->command;
    }
  }
  
  if (request) {
    FREE(request->def);
    FREE(request->buf);
    FREE(request);
  }
  if (response) {
    FREE(response->def);
    FREE(response->buf);
    FREE(response);
  }
  
  return result;
}