Example #1
0
/* Function: ProcessCancelLoggingPkt ===========================================
 * Receive and process the EXT_CANCEL_LOGGING packet.
 */
PRIVATE boolean_T ProcessCancelLoggingPkt(const int pktSize)
{
    const char *pkt;
    int32_T    upInfoIdx;
    boolean_T  error = EXT_NO_ERROR;

    pkt = GetPkt(pktSize);
    if (pkt == NULL) {
        SendResponseStatus(EXT_CANCEL_LOGGING_RESPONSE,
                           NOT_ENOUGH_MEMORY,
                           -1);
        error = EXT_ERROR;
        goto EXIT_POINT;
    }
            
    /* Extract upInfoIdx */
    (void)memcpy(&upInfoIdx, pkt, sizeof(int32_T));
            
    PRINT_VERBOSE(
        ("got EXT_CANCEL_LOGGING packet for upInfoIdx : %d\n", upInfoIdx));

    UploadCancelLogging(upInfoIdx);

    error = SendResponseStatus(EXT_CANCEL_LOGGING_RESPONSE,
                               STATUS_OK,
                               upInfoIdx);
    if (error != EXT_NO_ERROR) goto EXIT_POINT;

  EXIT_POINT:
    return(error);
} /* end ProcessCancelLoggingPkt */
Example #2
0
/* Function: ProcessArmTriggerPkt ==============================================
 * Receive and process the EXT_ARM_TRIGGER packet.
 */
PRIVATE boolean_T ProcessArmTriggerPkt(const int pktSize, int_T numSampTimes)
{
    const char *pkt;
    int32_T    upInfoIdx;
    boolean_T  error = EXT_NO_ERROR;

    pkt = GetPkt(pktSize);
    if (pkt == NULL) {
        SendResponseStatus(EXT_ARM_TRIGGER_RESPONSE,
                           NOT_ENOUGH_MEMORY,
                           -1);
        error = EXT_ERROR;
        goto EXIT_POINT;
    }

    /* Extract upInfoIdx */
    (void)memcpy(&upInfoIdx, pkt, sizeof(int32_T));

    PRINT_VERBOSE(
        ("got EXT_ARM_TRIGGER packet for upInfoIdx : %d\n", upInfoIdx));

    UploadArmTrigger(upInfoIdx, numSampTimes);

    error = SendResponseStatus(EXT_ARM_TRIGGER_RESPONSE,
                               STATUS_OK,
                               upInfoIdx);
    if (error != EXT_NO_ERROR) goto EXIT_POINT;

  EXIT_POINT:
    return(error);
} /* end ProcessArmTriggerPkt */
Example #3
0
/* Function: ProcessSetParamPkt ================================================
 * Receive and process the EXT_SETPARAM packet.
 */
PRIVATE boolean_T ProcessSetParamPkt(RTWExtModeInfo *ei,
                                     const int pktSize)
{
    int32_T    msg;
    const char *pkt;
    boolean_T  error = EXT_NO_ERROR;

    /*
     * Receive packet and set parameters.
     */
    pkt = GetPkt(pktSize);
    if (pkt == NULL) {
        msg = (int32_T)NOT_ENOUGH_MEMORY;
        SendPktToHost(EXT_SETPARAM_RESPONSE,sizeof(int32_T),(char_T *)&msg);
        error = EXT_ERROR;
        goto EXIT_POINT;
    }
    SetParam(ei, pkt);
   
    msg = (int32_T)STATUS_OK;
    
    error = SendPktToHost(EXT_SETPARAM_RESPONSE,sizeof(int32_T),(char_T *)&msg);
  
        
    if (error != EXT_NO_ERROR) goto EXIT_POINT;

EXIT_POINT:
   
    return(error);
} /* end ProcessSetParamPkt */
PRIVATE boolean_T AcknowledgeSignalActionPkt(const int pktSize, const ExtModeAction ACTION_ID)
{
    const char *pkt;
    int32_T    upInfoIdx;
    boolean_T  error = EXT_NO_ERROR;
    printf("Inside AcknowledgeSignalActionPkt \n");  //DAREN :added this here
    pkt = GetPkt(pktSize);
    (void)memcpy(&upInfoIdx, pkt, sizeof(int32_T));
    error = SendResponseStatus(ACTION_ID, STATUS_OK, upInfoIdx);
    return(error);
} 
PRIVATE boolean_T AcknowledgeSetParamPkt(const int pktSize)
{
    int32_T    msg;
    const char *pkt;
    boolean_T  error = EXT_NO_ERROR;
    printf("Inside AcknowledgeSetParamPkt \n");  //DAREN :added this here
    pkt = GetPkt(pktSize);
    msg = (int32_T)STATUS_OK;
    error = SendPktToHost(EXT_SETPARAM_RESPONSE, sizeof(int32_T), (char_T *)&msg);
    return(error);
}
Example #6
0
File: io.c Project: berkus/nemesis
static bool_t FileIO_GetPkt_m (
    IO_cl       *self,
    uint32_t     max_recs  /* IN */,
    IO_Rec_ptr   recs      /* IN */,
    Time_T       until     /* IN */,
    uint32_t    *nrecs     /* OUT */,
    word_t      *value     /* OUT */)
{
    FileIO_st     *st = self->st;
    
    return IO$GetPkt(st->io, max_recs, recs, until, nrecs, value);
}
/* Function: ProcessSelectTriggerSignalPkt ===========================================
 * Receive and process the EXT_SELECT_TRIGGER or EXT_SELECT_SIGNALS packet.
 */
PRIVATE boolean_T ProcessSelectTriggerSignalPkt(const ExtModeAction ACTION_ID, 
                                                RTWExtModeInfo *ei,
                                                const int pktSize,
                                                int_T numSampTimes,
                                                char* errMsg)
{
    const char *pkt;
    int32_T    upInfoIdx;
    boolean_T  error = EXT_NO_ERROR;
     printf("Inside ProcessSelectTriggerSignalPkt \n");  //DAREN :added this here
    pkt = GetPkt(pktSize);
    if (pkt == NULL) {
        SendResponseStatus(ACTION_ID, NOT_ENOUGH_MEMORY, -1);
        return(EXT_ERROR);
    }

    (void)memcpy(&upInfoIdx, pkt, sizeof(int32_T)); /* Extract upInfoIdx */
    switch(ACTION_ID) {
    case EXT_SELECT_TRIGGER_RESPONSE:
#ifndef EXTMODE_DISABLEPRINTF  
        PRINT_VERBOSE(
                    ("got EXT_SELECT_TRIGGER packet for upInfoIdx : %d\n", upInfoIdx));
#endif
        error = UploadInitTrigger(ei, pkt+sizeof(int32_T), upInfoIdx);
        break;
    case EXT_SELECT_SIGNALS_RESPONSE:
#ifndef EXTMODE_DISABLEPRINTF  
        PRINT_VERBOSE(
                    ("got EXT_SELECT_SIGNALS packet for upInfoIdx : %d\n", upInfoIdx));
#endif
        error = UploadLogInfoInit(ei, numSampTimes, pkt+sizeof(int32_T), upInfoIdx);
        break;
    default:
        break;
    }

    if (error != EXT_NO_ERROR) {
        SendResponseStatus(ACTION_ID, NOT_ENOUGH_MEMORY, upInfoIdx);
#ifndef EXTMODE_DISABLEPRINTF            
        printf("%s\n", errMsg);
#endif
        return(error);
    }

    error = SendResponseStatus(ACTION_ID, STATUS_OK, upInfoIdx);
    return(error); /* Can be EXT_NO_ERROR */
} /* end ProcessSelectTriggerSignalPkt */
Example #8
0
/* Function: ProcessSelectSignalsPkt ===========================================
 * Receive and process the EXT_SELECT_SIGNALS packet.
 */
PRIVATE boolean_T ProcessSelectSignalsPkt(RTWExtModeInfo *ei,
                                          int_T          numSampTimes,
                                          const int      pktSize)
{
    const char *pkt;
    int32_T    upInfoIdx;
    boolean_T  error = EXT_NO_ERROR;

    pkt = GetPkt(pktSize);
    if (pkt == NULL) {
        SendResponseStatus(EXT_SELECT_SIGNALS_RESPONSE,
                           NOT_ENOUGH_MEMORY,
                           -1);
        error = EXT_ERROR;
        goto EXIT_POINT;
    }

    /* Extract upInfoIdx */
    (void)memcpy(&upInfoIdx, pkt, sizeof(int32_T));

    PRINT_VERBOSE(
        ("got EXT_SELECT_SIGNALS packet for upInfoIdx : %d\n", upInfoIdx));

    error = UploadLogInfoInit(ei, numSampTimes, pkt+sizeof(int32_T), upInfoIdx);
    if (error != NO_ERR) {
        SendResponseStatus(EXT_SELECT_SIGNALS_RESPONSE,
                           NOT_ENOUGH_MEMORY,
                           upInfoIdx);
        printf(
            "\nError in UploadLogInfoInit(). Most likely a memory\n"
            "allocation error or an attempt to re-initialize the\n"
            "signal selection during the data logging process\n"
            "(i.e., multiple EXT_SELECT_SIGNAL packets were received\n"
            "before the logging session terminated or an\n"
            "EXT_CANCEL_LOGGING packet was received)\n");
        goto EXIT_POINT;
    }

    error = SendResponseStatus(EXT_SELECT_SIGNALS_RESPONSE,
                               STATUS_OK,
                               upInfoIdx);
    if (error != EXT_NO_ERROR) goto EXIT_POINT;

  EXIT_POINT:
    return(error);
} /* end ProcessSelectSignalsPkt */
/* Function: ProcessCancelLoggingArmTriggerPkt ===========================================
 * Receive and process the EXT_CANCEL_LOGGING or EXT_ARM_TRIGGER packet.
 */
PRIVATE boolean_T ProcessCancelLoggingArmTriggerPkt(const ExtModeAction ACTION_ID, 
						const int pktSize, 
						int_T numSampTimes)
{
    const char *pkt;
    int32_T    upInfoIdx;
    boolean_T  error = EXT_NO_ERROR;
    printf("Inside ProcessCancelLoggingArmTriggerPkt \n");  //DAREN :added this here
    pkt = GetPkt(pktSize);
    if (pkt == NULL) {
        SendResponseStatus(ACTION_ID, NOT_ENOUGH_MEMORY, -1);
        return(EXT_ERROR);
    }
            
    (void)memcpy(&upInfoIdx, pkt, sizeof(int32_T)); /* Extract upInfoIdx */
        
    switch(ACTION_ID) {
    case EXT_CANCEL_LOGGING_RESPONSE:
#ifndef EXTMODE_DISABLEPRINTF   
        PRINT_VERBOSE(
                ("got EXT_CANCEL_LOGGING packet for upInfoIdx : %d\n", upInfoIdx));
#endif
        UploadCancelLogging(upInfoIdx);
        break;
    case EXT_ARM_TRIGGER_RESPONSE:
#ifndef EXTMODE_DISABLEPRINTF
        PRINT_VERBOSE(
                ("got EXT_ARM_TRIGGER packet for upInfoIdx : %d\n", upInfoIdx));
#endif
        UploadArmTrigger(upInfoIdx, numSampTimes);
        break;
    default:
        break;
    }

    error = SendResponseStatus(ACTION_ID, STATUS_OK, upInfoIdx);
    return(error); /* Can be EXT_NO_ERROR */
} /* end ProcessCancelLoggingArmTriggerPkt */
Example #10
0
/* Handle the recv of otherwise unhandled packets */
void default_packet_rec(struct default_rec_st *rec_info)
{
    card_st     *cdst;
    char	*rxbuf;
    word_t	value;
    IO_Rec	rxrecs[2];
    int		header_size = 128;
    int		mtu = 1514;	/* XXX hardwired constants */
    int		i;
    intf_st	*intfp; 
    iphost_st	*host_st;
    bool_t	ok = False;    
    Net_IPHostAddr ipaddr;
    Net_IPHostAddr *ipaddrp;
    char	buf[32];
    uint32_t	rec_recs;       /* nr of recs the received in call */

    TRC(printf("packet recv running\n"));

    cdst    = rec_info->mycard;
    host_st = rec_info->myhost;
    intfp   = rec_info->intf;


    sprintf(buf, "svc>net>%s>ipaddr", intfp->name);
    ipaddrp = NAME_FIND(buf, Net_IPHostAddrP);
    ipaddr = *ipaddrp;

    intfp->def_txfilt = LMPFMod$NewTXDef(cdst->pfmod, cdst->mac, ipaddr.a);

    getDxIOs(cdst->netif, intfp->def_txfilt, "DEF",
		     /* RETURNS: */
		     &intfp->def_rxhdl, &intfp->def_txhdl,
		     &intfp->io_rx,      &intfp->io_tx,
		     &intfp->def_rxoff, &intfp->def_txoff,
		     &intfp->def_heap);

    /* sanity check what we got  */
    if (intfp->def_rxoff == NULL || intfp->def_rxhdl==0)
        printf("flowman: error: bad recv handle or offer\n");
    if (intfp->io_tx == NULL)
        printf("flowman: default handler: tx bind failed\n");    
    if (intfp->io_rx == NULL)
        printf("flowman: default handler: rx bind failed\n");
    if (intfp->def_heap == NULL)
        printf("flowman: default handler: def_heap == NULL\n");

    ok = Netif$SetTxFilter(cdst->netif, intfp->def_txhdl, intfp->def_txfilt);
    if (!ok)
        printf("flowman: cannot set tx filter\n");

    /* install default filter */
    ok = LMPFCtl$SetDefault(cdst->rx_pfctl, intfp->def_rxhdl);
    if (!ok)
        printf("flowman: cannot set rx default filter\n");

    /* set xxstat to 0 */
    memset(&host_st->ipstat,  0, sizeof(ipstat_st));
    memset(&host_st->tcpstat, 0, sizeof(tcpstat_st));
    memset(&host_st->udpstat, 0, sizeof(udpstat_st));

     /* Thiemo: should be something with time of day, so that it grows
      * after crashing */
    host_st->ip_id = NOW() & 0xffff;

    mtu = ALIGN4(mtu);

#define PIPEDEPTH 16
    rxbuf = Heap$Malloc(intfp->def_heap, PIPEDEPTH * (mtu + header_size));
    
    for(i=0; i<PIPEDEPTH; i++)
    {
        /* chop up memory */
        rxrecs[0].base = rxbuf + i*(mtu+header_size);
        rxrecs[0].len  = header_size;
        rxrecs[1].base = rxbuf + i*(mtu+header_size) + header_size;
        rxrecs[1].len  = mtu;

        /* send recs */
//	TRC(printf("prime : %p+%d %p+%d \n",
//		   rxrecs[0].base, rxrecs[0].len,
//		   rxrecs[1].base, rxrecs[1].len));

	/* Actually, want to skip the first 2 bytes of header, so Ethernet
	 * frames land mis-aligned, but IP layer and up is correctly
	 * aligned */
	((char *)rxrecs[0].base) += 2;
	rxrecs[0].len -= 2;
        if (!IO$PutPkt(intfp->io_rx, 2, rxrecs, 0, 0))
	    printf("flowman: default prime %d failed\n", i);

//        TRC(printf("prime %d sent\n", i));
    }

    while (1)
    {
        /* loop and get incoming packets */
	DTRC(printf("flowman: default: waiting for packet..\n"));
        
        IO$GetPkt(intfp->io_rx, 2, rxrecs, FOREVER, &rec_recs, &value);
	((char *)rxrecs[0].base) -= 2;
	rxrecs[0].len  += 2;

        DTRC(printf("flowman: got packet on default channel, "
		    "nr of IO_Recs %d, rec[0].len=%d\n",
		    rec_recs, rxrecs[0].len));

        ether_input(rxrecs, rec_recs, cdst->mac, host_st);

        /* send down an empty packet after adapting to orig. size */
	/* XXX check base */
        rxrecs[0].len = header_size;
        rxrecs[1].len = mtu-header_size;

	/* again, send down the version which is advanced slightly */
	((char *)rxrecs[0].base) += 2;
	rxrecs[0].len -= 2;
	IO$PutPkt(intfp->io_rx, 2, rxrecs, 0, 0);
    }
}
Example #11
0
/* 
 * Handle mouse events.  Keep track of x, y and button state 
 */
void HandleMouseEvent( WSSvr_st *st, Mouse_Event *ev )
{
    Mouse_st *mst = &st->mouse_st;
    /* the volatile on the next line is to work around a bug in the
     * arm backend of gcc in version 2.7.2 - it is fixed in 2.7.90 */
    volatile int32_t newx, newy;

    /*
     * Handle mouse motion
     */
    if (ev->dx || ev->dy) {

	FB_MgrPkt *pkt;
	IO_Rec    rec;
	word_t value;
	
	newx = mst->x + ev->dx;
	if( newx < 0 ) {
	    newx = 0;
	}
	if( newx >= st->fb_st.width ) {
	    newx = st->fb_st.width-1;
	}
	
	newy = mst->y - ev->dy;
	if( newy < 0 ) newy = 0;
	if( newy >= st->fb_st.height )
	    newy = st->fb_st.height-1;

	mst->x = newx;
	mst->y = newy;

	if(st->mgr_io) {
	    uint32_t slots;
	    IO$GetPkt(st->mgr_io, 1, &rec, FOREVER, &slots, &value);
	    
	    pkt = (FB_MgrPkt *)rec.base;
	    
	    pkt->tag = FB_MgrPktType_Mouse;
	    pkt->u.Mouse.index = st->fb_st.cursor;
	    pkt->u.Mouse.x = st->mouse_st.x;
	    pkt->u.Mouse.y = st->mouse_st.y;
	    
	    rec.base = pkt;
	    rec.len = sizeof(FB_MgrPkt);
	    
	    /* This won't block as long as the FB has implemented an
               IOCallPriv */
	    
	    IO$PutPkt(st->mgr_io, 1, &rec, 1, FOREVER);
	} else {

	    /* The FB has not provided a manager stream for some reason */
	    FB$SetCursor(st->fb_st.fb, st->fb_st.cursor, st->mouse_st.x,
			 st->mouse_st.y); 
	}
	
	MU_LOCK(&st->mu);

	Refocus(st);

	MU_RELEASE(&st->mu);

    }

    /*
     * Handle buttons
     */
    
    mst->buttons = ev->buttons;
    
    /* Send a WSEvent */
    {
	WS_Event      wsev;
	WS_MouseData  *md = &wsev.d.u.Mouse;
	
	wsev.d.tag  = WS_EventType_Mouse;
	wsev.t      = ev->time;
	md->buttons = mst->buttons;
	md->x       = mst->x - st->focus->x;
	md->y       = mst->y - st->focus->y;
	md->absx    = mst->x;
	md->absy    = mst->y;
	
	MU_LOCK(&st->mu);
	EventDeliver(st, st->focus, &wsev, True);
	MU_RELEASE(&st->mu);
    }    

}
Example #12
0
static int udp_select(struct socket *sock, int nfds,
		      fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
		      struct timeval *timeout)
{
    IO_Rec rec;
    uint32_t nrecs;
    word_t value;
    Time_ns t;
    struct udp_data *udp_data= (struct udp_data *)sock->data;

    MU_LOCK(&sock->lock);

    /* XXX really want to keep a domain-wide cache of connections */
    if(sock->state != SS_CONNECTED) /* stack needs building */
    {
	struct sockaddr_in *laddr = (struct sockaddr_in *)&(sock->laddr);

	/* remote address isn't used for anything in recv */
	build_stack(udp_data, laddr, NULL);
	sock->state = SS_CONNECTED;
    }
    MU_RELEASE(&sock->lock);
    MU_LOCK(&sock->rxlock);

    if (timeout)
    {
	t = NOW() + 
	    timeout->tv_sec * SECONDS(1) + 
	    timeout->tv_usec * MICROSECS(1);
    }
    else
    {
	t = FOREVER;
    }

    value = 0;
    IO$GetPkt(udp_data->rxio, 0, &rec, t, &nrecs, &value);
    if (value)
    {
	eprintf("udp_select: got a packet cx?!?\n");
	ntsc_dbgstop();
    }

#ifdef PARANOID
    if (NOW() > t + SECONDS(2))
	printf("udp_select: warning: took >2 secs to return from select?\n");
#endif

    MU_RELEASE(&sock->rxlock);

    if (nrecs)
    {
//	eprintf("sel ok\n");
	return 1;  /* there's data available */
    }
    else
    {
//	eprintf("sel t/o\n");
	return 0;  /* no data, but not an error - we timed out */
    }
}
Example #13
0
static int udp_send(struct socket *sock, const char *message, int len,
		    int flags, const struct sockaddr *dest_addr, int dest_len)
{
    struct udp_data *udp_data= (struct udp_data *)sock->data;
    IO_Rec txrecs[3];
    struct sockaddr_in *laddr= (struct sockaddr_in *)&(sock->laddr);
    struct sockaddr_in *raddr= (struct sockaddr_in *)&(sock->raddr);
    int i;
    uint32_t nrecs;
    pktcx_t *pktcx;

    TRC(eprintf("udp_send: entered\n"));

    MU_LOCK(&sock->lock);

    if(sock->state != SS_CONNECTED) /* stack needs building */
    {
	if (dest_addr)
	{
	    *raddr = *(struct sockaddr_in *)dest_addr;
	}
	else
	{
	    MU_RELEASE(&sock->lock);
	    return -1; /* ENOTCONN or summit */
	}

	TRC(eprintf("udp_send: building stack\n"));
	build_stack(udp_data, laddr, NULL);
	sock->state = SS_CONNECTED;

	/* now target it */
	TRC(eprintf("udp_send: retargeting to %I:%d\n",
		    raddr->sin_addr, raddr->sin_port));
	if(!retarget(udp_data, laddr, raddr)) {
	    TRC(eprintf("...retarget failed\n"));
	    /* ARP failed */
	    MU_RELEASE(&sock->lock);
	    return -1; /* EHOSTDOWN or sim */
	}
    }
    else
    {
	struct sockaddr_in *daddr = (struct sockaddr_in *)dest_addr;

	TRC(eprintf("udp_send: stack already built\n"));
	if (daddr->sin_addr.s_addr == raddr->sin_addr.s_addr
	    && daddr->sin_port == raddr->sin_port)
	{
	    TRC(eprintf("... and targeted correctly\n"));
	}
	else
	{
	    TRC(eprintf("... but incorrectly targeted; retargeting\n"));
	    /* retarget stack for this destination */
	    if(!retarget(udp_data, laddr, daddr)) {
		/* ARP failed */
		MU_RELEASE(&sock->lock);
		return -1; /* EHOSTDOWN or sim */
	    }
	    *raddr = *daddr;
	    TRC(eprintf("udp_send: retargeted stack\n"));
	}
    }

    /* done with global state, now need the acquire the receive resource
     * lock */
    MU_RELEASE(&sock->lock);
    MU_LOCK(&sock->txlock);

    /* organise mem for headers */
    txrecs[0].len  = udp_data->head;
    txrecs[0].base = udp_data->txbuf;

    /* 
    ** XXX SMH: for the moment, we must copy the data to be transmitted
    ** onto a heap which is readable by the driver domain. This is not, 
    ** however, the most efficient way one can imagine doing transmit.
    ** Some alternatives that should be investigated are:
       a) make the driver enter kernel mode s.t. it can read the data.
          This is essentially what used to happen before coz drivers
	  ran in kernel mode the entire time. 
       b) map the clients data readable to the driver domain on the fly.
          This would require some way of getting hold of the stretch
	  containing the message buffer, and might be a very bad idea
	  indeed coz lots of other stuff would be mapped too.
       c) force clients to give us data which is readable by the driver
          pdom. This is trickier than it sounds since in general clients
	  won't know the pdom of the driver for the interface upon which
	  their message will eventually be transmitted. Though we could
	  arrange for all network drivers to be in the same pdom (!?!).
    ** Even apart from those considerations, this temporary solution should
    ** be modified s.t. the mallocing is done out of band, or not at all
    ** [i.e. perhaps have a stretch, not a heap, and then can just memcpy
    **  to the start of this. requires some locking though ;-]
    */
    txrecs[1].len  = len;
    if(!(txrecs[1].base = Heap$Malloc(udp_data->txheap, len))) {
	eprintf("udp_send: failed to malloc txrec buf!\n"); 
	MU_RELEASE(&sock->txlock); 
	return -1;   /* error */
    }
    memcpy((char *)txrecs[1].base, message, len);

    if(!(pktcx = Heap$Calloc(udp_data->txheap, sizeof(pktcx_t), 1))) {
	eprintf("udp_send: failed to malloc packet context!\n"); 
	Heap$Free(udp_data->txheap, txrecs[1].base);
	MU_RELEASE(&sock->txlock); 
	return -1;   /* error */
    }

    pktcx->ri_nrecs = 2;
    for(i=0; i<2; i++)
	pktcx->ri_recs[i] = txrecs[i];

    TRC(eprintf("udp_send: About to IO$PutPkt...\n"));


    if (!IO$PutPkt(udp_data->txio, 2, txrecs, (word_t)pktcx, FOREVER))
    {
	txrecs[1].len = -1;  /* error */
	goto out;
    }

    /* pick up the tx buffer from the driver */
    do {
	IO$GetPkt(udp_data->txio, 2, txrecs, NOW() + SECONDS(10),
		  &nrecs, (word_t*)&pktcx);
	if (nrecs == 0) {
	    printf("udp_send: timeout recovering tx buffers\n");
	} else {
	    if (nrecs != 2)
	    {
		printf("udp_send: didn't recover enough tx buffers (%d!=3)\n",
		       nrecs);
	    }
	}
    } while(nrecs != 2);
    if (!pktcx)
	printf("udp_send: didn't get packet context back?\n");
    if (pktcx && pktcx->error)
	printf("udp_send: error %d sending\n", pktcx->error);

out:
    Heap$Free(udp_data->txheap, txrecs[1].base);
    Heap$Free(udp_data->txheap, pktcx);

    MU_RELEASE(&sock->txlock);

    return txrecs[1].len;
}
Example #14
0
/* 
** listen doesn't make much sense on UDP
*/
static int udp_listen(struct socket *sock)
{
    printf("XXX bad call listen on udp/dgram/inet socket.\n");
    return -1;
}


#define MAXRECS 18	/* which is enough for 6 fragments */
static int udp_recv(struct socket *sock, char *buffer, int length, int flags, 
		    struct sockaddr *address, int *address_len)
{
    struct sockaddr_in *inaddr  = (struct sockaddr_in *)address;
    struct udp_data    *udp_data= (struct udp_data *)sock->data;
    IO_Rec rxrecs[MAXRECS];
    word_t value;
    uint32_t nrecs;
    uint32_t cnt=0;
    int rxlen=0;
    int i;
    pktcx_t *pktcx, *np;

    MU_LOCK(&sock->lock);

    /* XXX really want to keep a domain-wide cache of connections */
    if(sock->state != SS_CONNECTED) /* stack needs building */
    {
	struct sockaddr_in *laddr = (struct sockaddr_in *)&(sock->laddr);

	/* remote address isn't used for anything in recv */
	build_stack(udp_data, laddr, NULL);
	sock->state = SS_CONNECTED;
    }

    /* done with global state, now need the acquire the receive resource
     * lock */
    MU_RELEASE(&sock->lock);
    MU_LOCK(&sock->rxlock);

    do {
	/* organise mem for header */
	IO$GetPkt(udp_data->rxio, MAXRECS, rxrecs, FOREVER, &nrecs, &value);
	pktcx = (void*)value;
	if (nrecs > MAXRECS)
	{
	    printf("udp_recv: %d recs needed, only %d supplied\n",
		   nrecs, MAXRECS);
	    goto fail;
	}
	if (!pktcx)
	{
	    printf("udp_recv: didn't get back a pktcx?\n");
	    goto fail;
	}
	if (nrecs > 0)
	{
	    for(i=1; i<nrecs; i++)
	    {
		if (rxrecs[i].len == 0)
		    continue;  /* skip empty recs */
		cnt = MIN(rxrecs[i].len, length);
		if (cnt == 0)
		    break;	/* out of client buffer */
		memcpy(buffer, rxrecs[i].base, cnt);
		buffer += cnt;
		length -= cnt;
		rxlen += cnt;
	    }
	}
	else /* nrecs == 0 */
	{
	    /* no valid data, but the packet context probably contains
	     * some recs for us, so recyle the buffers and try
	     * receiving again */
	    eprintf("udp: recycle (shouldn't happen)\n");
	    while(pktcx)
	    {
		np = pktcx->next;
		pktcx->next = NULL;	/* break any chain */
		pktcx->error = 0;
		pktcx->cid = 0;
		IO$PutPkt(udp_data->rxio, pktcx->ri_nrecs, pktcx->ri_recs,
			  (word_t)pktcx, FOREVER);
		pktcx = np;
	    }
	    /* back to the top... */
	}
    } while(nrecs == 0);

    if (cnt == 0)
    {
	printf("udp_recv: warning: truncated the received packet "
		"to fit buffer\n");
    }
    
    TRC(eprintf("udp_recv: got back %d recs.\n", nrecs));

    if (inaddr)
    {
	FlowMan_SAP sap;

	inaddr->sin_family = AF_INET;
	if (UDP$GetLastPeer(udp_data->udp, &sap))
	    inaddr->sin_addr.s_addr = sap.u.UDP.addr.a;
	else
	    inaddr->sin_addr.s_addr = 0;  /* IP layer not present */
	inaddr->sin_port = sap.u.UDP.port;
	*address_len = sizeof(*inaddr);
    }

    /* send empty buffer(s) back down */
    TRC(eprintf("udp_recv: sending buffers back down\n"));
    while(pktcx)
    {
	np = pktcx->next;
	pktcx->next = NULL;	/* break any chain */
	pktcx->error = 0;
	pktcx->cid = 0;
	nrecs = pktcx->ri_nrecs;
	for(i=0; i<nrecs; i++)
	    rxrecs[i] = pktcx->ri_recs[i];
	IO$PutPkt(udp_data->rxio, nrecs, rxrecs, (word_t)pktcx, FOREVER);
	pktcx = np;
    }

    MU_RELEASE(&sock->rxlock);
    return rxlen;

fail:
    MU_RELEASE(&sock->rxlock);
    return -1;
}
Example #15
0
File: io.c Project: berkus/nemesis
/* ---------------------------------- Server side IO implementation ---- */
PUBLIC void IOThread(disk_t *disk)
{
    stream_t *stream;
    QoSEntry_clp qosentry = disk->qosentry;
    Time_T pre,post;
    IO_clp io;
    IO_Rec recs[2]; 
    uint32_t nrecs;
    word_t value;
    uint32_t offset;
    Time_ns cost;
    uint32_t  notify;
    USD_Extent ext;

    FileIO_Request copyreq;
    FileIO_Request *req;

    while (True) {
	TRC(printf(__FUNCTION__": about to Rendezvous...\n"));
	io = IOEntry$Rendezvous((IOEntry_clp)qosentry, FOREVER);

	/* 
	** Account the time we're about to spend processing this packet
	** to the QosEntry: for now, we just are sych. and so can 
	** actually count the amount of time. XXX no overhead accounted.
	*/
	pre = NOW();

	TRC(printf(__FUNCTION__": back from Rdzvs, io at %p\n", io));

	/* Find out whose IO it is */
	stream = (stream_t *)IO_HANDLE(io);
	offset = stream->usd->partition->p_offset;

	TRC(printf("(It's stream %d)\n",stream->sid));

	/* XXX SMH: nasty hardwired request/buffer IO_Rec pair */
	if (IO$GetPkt(io, 2, recs, 0, &nrecs, &value)) {
	    
	    FTRC("got packet.\n");

	    req = (FileIO_Request *)recs[0].base;
	
	    copyreq = *req;

	    IOTRC(printf("req=%p\n",req));

	    IOTRC(printf("%qx:(%qd,%d)\n", stream->sid, 
			 copyreq.blockno, copyreq.nblocks));
	
	    /* Translate the addresses in the request */
	    if(!USDCallback$Translate(stream->usd->callbacks,
				      stream->sid,
				      stream->cid,
				      &copyreq,
				      &ext,
				      &notify))
	    {
		TRC(printf("denied %qx:(%qd,%x)\n", stream->sid,
			   copyreq.blockno, copyreq.nblocks));
		req->rc = FileIO_RC_DENIED;
		goto denied;
	    }

	    /* Actually do the transaction */
	    switch(copyreq.op) {
	    case FileIO_Op_Read:
		FTRC("trying to read.\n");
		MU_LOCK(&disk->mu);
		if (BlockDev$Read((BlockDev_clp)disk->device, 
			      ext.base + offset, 
			      ext.len, 
				  recs[1].base)) {
		  req->rc = FileIO_RC_OK;
		  FTRC("done.\n");
		}
		else {
		  req->rc = FileIO_RC_FAILURE;
		  FTRC("failure trying to read.\n");
		}
		MU_RELEASE(&disk->mu);
		break; 
		
	    case FileIO_Op_Write:
		FTRC("trying to write.\n");
		MU_LOCK(&disk->mu);
		if (BlockDev$Write((BlockDev_clp)disk->device, 
			       ext.base + offset, 
			       ext.len, 
				   recs[1].base)) {
		  req->rc = FileIO_RC_OK;
		  FTRC("done.\n");
		}
		else {
		  req->rc = FileIO_RC_FAILURE;
		  FTRC("failure trying to write.\n");
		}
		MU_RELEASE(&disk->mu);
		break;

	    case FileIO_Op_Sync:
		FTRC("trying to sync.\n");
		printf(__FUNCTION__": FileIO_Op_Sync unimplemented.\n");
		FTRC("done.\n");
		break;

	    default:
		printf(__FUNCTION__": bad FileIO_Op %x\n", copyreq.op);
		ntsc_dbgstop();
	    }

	    USDCallback$Notify(stream->usd->callbacks,
			       stream->sid,
			       stream->cid,
			       &copyreq,
			       &ext,
			       notify,
			       recs[1].base);
	denied:
	    post = NOW();
	    cost = post - pre;
	    QoSEntry$Charge(qosentry, io, cost);
	
	    /* Return the IO_Rec vector */
	    TRC(printf("USD$IOThread: returning IOs.\n"));
	    IO$PutPkt(io, nrecs, &recs[0], cost, 0);
	}    
    } /* while true */

    printf("USD$IOThread: BAD NEWS. Exiting (?)\n");
}