Example #1
0
void pit_isr0() //电机控制5ms
{  
  //读脉冲
	pulsecount = LPLD_LPTMR_GetPulseAcc();
	pulseaccu += pulsecount;
  //pulsetotal+=pulsecount;
	LPLD_LPTMR_Reset();       
	LPLD_LPTMR_Init(MODE_PLACC, 0, LPTMR_ALT1, IRQ_DISABLE, NULL);
  
  
  //分析
  //  analyse();
  //控制
	scan_infrared(r1, r2, r3, r4);
  //fisrthongwaierror();
  //secondhongwaierror();//边沿跳变获得误差
	calculate_infrared_error(r1, INFRARED_LINE1_NUM, &r1_error);
	calculate_infrared_error(r2, INFRARED_LINE2_NUM, &r2_error);
  
	if (is_enabled) do_control();
	else do_stop();
  
	static int __scan_infront_counter = 0;
	
	if (__adc > SCAN_INFRONT_THRESHOLE_SMALL 
		&& abs(r1_error - r2_error) < 2) __scan_infront_counter ++;
	else {
		__scan_infront_counter = 0;
	}
	is_car_infront = __scan_infront_counter > 5;
}
Example #2
0
int process(char **args) {
    int return_val = 0;
    
    if (args[0] == NULL) {
        return_val = 0;
    } else if (is_control(args[0])) {
        return_val = do_control(args);
    } else if (is_ok()) {
        if (!internal(args, &return_val)) {
            return_val = execute(args);
        }
    }
    return return_val;
}
Example #3
0
File: dopdu.c Project: aeppert/pcp
/*
 * Service a request from the pmlogger client.
 * Return non-zero if the client has closed the connection.
 */
int
client_req(void)
{
    int		sts;
    __pmPDU	*pb;
    __pmPDUHdr	*php;
    int		pinpdu;

    if ((pinpdu = sts = __pmGetPDU(clientfd, ANY_SIZE, TIMEOUT_DEFAULT, &pb)) <= 0) {
	if (sts != 0)
	    fprintf(stderr, "client_req: %s\n", pmErrStr(sts));
	return 1;
    }
    if (qa_case == QA_SLEEPY) {
	/* error injection - delay before processing and responding */
	sleep(5);
    }
    php = (__pmPDUHdr *)pb;
    sts = 0;

    switch (php->type) {
	case PDU_CREDS:		/* version 2 PDU */
	    sts = do_creds(pb);
	    break;
	case PDU_LOG_REQUEST:	/* version 2 PDU */
	    sts = do_request(pb);
	    break;
	case PDU_LOG_CONTROL:	/* version 2 PDU */
	    sts = do_control(pb);
	    break;
	default:		/*  unknown PDU  */
	    fprintf(stderr, "client_req: bad PDU type 0x%x\n", php->type);
	    sts = PM_ERR_IPC;
	    break;
    }
    if (pinpdu > 0)
	__pmUnpinPDUBuf(pb);
    
    if (sts >= 0)
	return 0;
    else {
	/* the client isn't playing by the rules */
	__pmSendError(clientfd, FROM_ANON, sts);
	return 1;
    }
}
Example #4
0
static void do_service(config_t *cpe, config_t *config, struct rs_config *rs_config)
{
	struct rs_start *rs_start = &rs_config->rs_start;
	config_t *cp;

	/* At this point we expect one sublist that contains the varios
	 * resource allocations
	 */
	if (!(cpe->flags & CFG_SUBLIST))
	{
		fatal("do_service: expected list at %s:%d",
			cpe->file, cpe->line);
	}
	if (cpe->next != NULL)
	{
		cpe= cpe->next;
		fatal("do_service: expected end of list at %s:%d",
			cpe->file, cpe->line);
	}
	cpe= cpe->list;

	/* Process the list */
	for (cp= cpe; cp; cp= cp->next)
	{
		if (!(cp->flags & CFG_SUBLIST))
		{
			fatal("do_service: expected list at %s:%d",
				cp->file, cp->line);
		}
		cpe= cp->list;
		if ((cpe->flags & CFG_STRING) || (cpe->flags & CFG_SUBLIST))
		{
			fatal("do_service: expected word at %s:%d",
				cpe->file, cpe->line);
		}

		if (strcmp(cpe->word, KW_CLASS) == 0)
		{
			do_class(cpe->next, config, rs_config);
			continue;
		}
		if (strcmp(cpe->word, KW_UID) == 0)
		{
			do_uid(cpe->next, rs_start);
			continue;
		}
		if (strcmp(cpe->word, KW_SIGMGR) == 0)
		{
			do_sigmgr(cpe->next, rs_start);
			continue;
		}
		if (strcmp(cpe->word, KW_TYPE) == 0)
		{
			do_type(cpe->next, rs_config);
			continue;
		}
		if (strcmp(cpe->word, KW_DESCR) == 0)
		{
			do_descr(cpe->next, rs_config);
			continue;
		}
		if (strcmp(cpe->word, KW_SCHEDULER) == 0)
		{
			do_scheduler(cpe->next, rs_start);
			continue;
		}
		if (strcmp(cpe->word, KW_PRIORITY) == 0)
		{
			do_priority(cpe->next, rs_start);
			continue;
		}
		if (strcmp(cpe->word, KW_QUANTUM) == 0)
		{
			do_quantum(cpe->next, rs_start);
			continue;
		}
		if (strcmp(cpe->word, KW_CPU) == 0)
		{
			do_cpu(cpe->next, rs_start);
			continue;
		}
		if (strcmp(cpe->word, KW_IRQ) == 0)
		{
			do_irq(cpe->next, rs_start);
			continue;
		}
		if (strcmp(cpe->word, KW_IO) == 0)
		{
			do_io(cpe->next, rs_start);
			continue;
		}
		if (strcmp(cpe->word, KW_PCI) == 0)
		{
			do_pci(cpe->next, rs_start);
			continue;
		}
		if (strcmp(cpe->word, KW_SYSTEM) == 0)
		{
			do_system(cpe->next, rs_start);
			continue;
		}
		if (strcmp(cpe->word, KW_IPC) == 0)
		{
			do_ipc(cpe->next, rs_start);
			continue;
		}
		if (strcmp(cpe->word, KW_VM) == 0)
		{
			do_vm(cpe->next, rs_start);
			continue;
		}
		if (strcmp(cpe->word, KW_CONTROL) == 0)
		{
			do_control(cpe->next, rs_start);
			continue;
		}
	}
}
Example #5
0
void network_thread ()
{
    /*
     * We loop forever waiting on either data from the ppp drivers or from
     * our network socket.  Control handling is no longer done here.
     */
    struct sockaddr_in from;
    struct in_pktinfo to;
    unsigned int fromlen;
    int tunnel, call;           /* Tunnel and call */
    int recvsize;               /* Length of data received */
    struct buffer *buf;         /* Payload buffer */
    struct call *c, *sc;        /* Call to send this off to */
    struct tunnel *st;          /* Tunnel */
    fd_set readfds;             /* Descriptors to watch for reading */
    int max;                    /* Highest fd */
    struct timeval tv, *ptv;    /* Timeout for select */
    struct msghdr msgh;
    struct iovec iov;
    char cbuf[256];
    unsigned int refme, refhim;
    int * currentfd;
    int server_socket_processed;

#ifdef HIGH_PRIO
    /* set high priority */
    if (setpriority(PRIO_PROCESS, 0, -20) < 0)
	l2tp_log (LOG_INFO, "xl2tpd: can't set priority to high: %m");
#endif

    /* This one buffer can be recycled for everything except control packets */
    buf = new_buf (MAX_RECV_SIZE);

    tunnel = 0;
    call = 0;

    for (;;)
    {
        int ret;
        process_signal();
        max = build_fdset (&readfds);
        ptv = process_schedule(&tv);
        ret = select (max + 1, &readfds, NULL, NULL, ptv);

        if (ret <= 0)
        {
#ifdef DEBUG_MORE
            if (ret == 0)
            {
                if (gconfig.debug_network)
                {
                    l2tp_log (LOG_DEBUG, "%s: select timeout\n", __FUNCTION__);
                }
            }
            else
            {
                if (gconfig.debug_network)
                {
                    l2tp_log (LOG_DEBUG,
                        "%s: select returned error %d (%s)\n",
                        __FUNCTION__, errno, strerror (errno));
                }
            }
#endif
            continue;
        }

        if (FD_ISSET (control_fd, &readfds))
        {
            do_control ();
        }
        server_socket_processed = 0;
        currentfd = NULL;
        st = tunnels.head;
        while (st || !server_socket_processed) {
            if (st && (st->udp_fd == -1)) {
                st=st->next;
                continue;
            }
            if (st) {
                currentfd = &st->udp_fd;
            } else {
                currentfd = &server_socket;
                server_socket_processed = 1;
            }
            if (FD_ISSET (*currentfd, &readfds))
        {
            /*
             * Okay, now we're ready for reading and processing new data.
             */
            recycle_buf (buf);

            /* Reserve space for expanding payload packet headers */
            buf->start += PAYLOAD_BUF;
            buf->len -= PAYLOAD_BUF;

	    memset(&from, 0, sizeof(from));
	    memset(&to,   0, sizeof(to));
	    
	    fromlen = sizeof(from);
	    
	    memset(&msgh, 0, sizeof(struct msghdr));
	    iov.iov_base = buf->start;
	    iov.iov_len  = buf->len;
	    msgh.msg_control = cbuf;
	    msgh.msg_controllen = sizeof(cbuf);
	    msgh.msg_name = &from;
	    msgh.msg_namelen = fromlen;
	    msgh.msg_iov  = &iov;
	    msgh.msg_iovlen = 1;
	    msgh.msg_flags = 0;
	    
	    /* Receive one packet. */
	    recvsize = recvmsg(*currentfd, &msgh, 0);

            if (recvsize < MIN_PAYLOAD_HDR_LEN)
            {
                if (recvsize < 0)
                {
                    if (errno == ECONNREFUSED) {
                        close(*currentfd);
                    }
                    if ((errno == ECONNREFUSED) ||
                        (errno == EBADF)) {
                        *currentfd = -1;
                    }
                    if (errno != EAGAIN)
                        l2tp_log (LOG_WARNING,
                             "%s: recvfrom returned error %d (%s)\n",
                             __FUNCTION__, errno, strerror (errno));
                }
                else
                {
                    l2tp_log (LOG_WARNING, "%s: received too small a packet\n",
                         __FUNCTION__);
                }
                if (st) st=st->next;
		continue;
            }


	    refme=refhim=0;


		struct cmsghdr *cmsg;
		/* Process auxiliary received data in msgh */
		for (cmsg = CMSG_FIRSTHDR(&msgh);
			cmsg != NULL;
			cmsg = CMSG_NXTHDR(&msgh,cmsg)) {
			/* extract destination(our) addr */
			if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) {
				struct in_pktinfo* pktInfo = ((struct in_pktinfo*)CMSG_DATA(cmsg));
				to = *pktInfo;
			}
			/* extract IPsec info out */
			else if (gconfig.ipsecsaref && cmsg->cmsg_level == IPPROTO_IP
			&& cmsg->cmsg_type == gconfig.sarefnum) {
				unsigned int *refp;
				
				refp = (unsigned int *)CMSG_DATA(cmsg);
				refme =refp[0];
				refhim=refp[1];
			}
		}

	    /*
	     * some logic could be added here to verify that we only
	     * get L2TP packets inside of IPsec, or to provide different
	     * classes of service to packets not inside of IPsec.
	     */
	    buf->len = recvsize;
	    fix_hdr (buf->start);
	    extract (buf->start, &tunnel, &call);

	    if (gconfig.debug_network)
	    {
		l2tp_log(LOG_DEBUG, "%s: recv packet from %s, size = %d, "
			 "tunnel = %d, call = %d ref=%u refhim=%u\n",
			 __FUNCTION__, inet_ntoa (from.sin_addr),
			 recvsize, tunnel, call, refme, refhim);
	    }

	    if (gconfig.packet_dump)
	    {
		do_packet_dump (buf);
	    }
			if (!(c = get_call (tunnel, call, from.sin_addr,
			       from.sin_port, refme, refhim)))
	    {
				if ((c = get_tunnel (tunnel, from.sin_addr.s_addr, from.sin_port)))
		{
		    /*
		     * It is theoretically possible that we could be sent
		     * a control message (say a StopCCN) on a call that we
		     * have already closed or some such nonsense.  To
		     * prevent this from closing the tunnel, if we get a
		     * call on a valid tunnel, but not with a valid CID,
		     * we'll just send a ZLB to ack receiving the packet.
		     */
		    if (gconfig.debug_tunnel)
			l2tp_log (LOG_DEBUG,
				  "%s: no such call %d on tunnel %d. Sending special ZLB\n",
				  __FUNCTION__, call, tunnel);
		    if (handle_special (buf, c, call) == 0)
			/* get a new buffer */
			buf = new_buf (MAX_RECV_SIZE);
		}
#ifdef DEBUG_MORE
		else{
		    l2tp_log (LOG_DEBUG,
			      "%s: unable to find call or tunnel to handle packet.  call = %d, tunnel = %d Dumping.\n",
			      __FUNCTION__, call, tunnel);
		    }
#endif
	    }
	    else
	    {
		if (c->container) {
			c->container->my_addr = to;
		}

		buf->peer = from;
		/* Handle the packet */
		c->container->chal_us.vector = NULL;
		if (handle_packet (buf, c->container, c))
		{
		    if (gconfig.debug_tunnel)
			l2tp_log (LOG_DEBUG, "%s: bad packet\n", __FUNCTION__);
		}
		if (c->cnu)
		{
		    /* Send Zero Byte Packet */
		    control_zlb (buf, c->container, c);
		    c->cnu = 0;
		}
		}
	}
	if (st) st=st->next;
	}

	/*
	 * finished obvious sources, look for data from PPP connections.
	 */
	st = tunnels.head;
        while (st)
        {
            sc = st->call_head;
            while (sc)
            {
                if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds))
                {
                    /* Got some payload to send */
                    int result;

                    while ((result = read_packet (sc)) > 0)
                    {
                        add_payload_hdr (sc->container, sc, sc->ppp_buf);
                        if (gconfig.packet_dump)
                        {
                            do_packet_dump (sc->ppp_buf);
                        }


                        sc->prx = sc->data_rec_seq_num;
                        if (sc->zlb_xmit)
                        {
                            deschedule (sc->zlb_xmit);
                            sc->zlb_xmit = NULL;
                        }
                        sc->tx_bytes += sc->ppp_buf->len;
                        sc->tx_pkts++;
                        udp_xmit (sc->ppp_buf, st);
                        recycle_payload (sc->ppp_buf, sc->container->peer);
                    }
                    if (result != 0)
                    {
                        l2tp_log (LOG_WARNING,
                             "%s: tossing read packet, error = %s (%d).  Closing call.\n",
                             __FUNCTION__, strerror (-result), -result);
                        strcpy (sc->errormsg, strerror (-result));
                        sc->needclose = -1;
                    }
                }
                sc = sc->next;
            }
            st = st->next;
        }
    }

}
Example #6
0
void network_thread ()
{
    /*
     * We loop forever waiting on either data from the ppp drivers or from
     * our network socket.  Control handling is no longer done here.
     */
    struct sockaddr_in from, to;
    unsigned int fromlen, tolen;
    int tunnel, call;           /* Tunnel and call */
    int recvsize;               /* Length of data received */
    struct buffer *buf;         /* Payload buffer */
    struct call *c, *sc;        /* Call to send this off to */
    struct tunnel *st;          /* Tunnel */
    fd_set readfds;             /* Descriptors to watch for reading */
    int max;                    /* Highest fd */
    struct timeval tv, *ptv;    /* Timeout for select */
    struct msghdr msgh;
    struct iovec iov;
    char cbuf[256];
    unsigned int refme, refhim;

    /* This one buffer can be recycled for everything except control packets */
    buf = new_buf (MAX_RECV_SIZE);

    tunnel = 0;
    call = 0;

    for (;;)
    {
        int ret;
        process_signal();
        max = build_fdset (&readfds);
        ptv = process_schedule(&tv);
        ret = select (max + 1, &readfds, NULL, NULL, ptv);
        if (ret <= 0)
        {
            if (ret == 0)
            {
                if (gconfig.debug_network)
                {
                    l2tp_log (LOG_DEBUG, "%s: select timeout\n", __FUNCTION__);
                }
            }
            else
            {
                if (gconfig.debug_network)
                {
                    l2tp_log (LOG_DEBUG,
                        "%s: select returned error %d (%s)\n",
                        __FUNCTION__, errno, strerror (errno));
                }
            }
            continue;
        }
        if (FD_ISSET (control_fd, &readfds))
        {
            do_control ();
        }
        if (FD_ISSET (server_socket, &readfds))
        {
            /*
             * Okay, now we're ready for reading and processing new data.
             */
            recycle_buf (buf);

            /* Reserve space for expanding payload packet headers */
            buf->start += PAYLOAD_BUF;
            buf->len -= PAYLOAD_BUF;

	    memset(&from, 0, sizeof(from));
	    memset(&to,   0, sizeof(to));
	    
	    fromlen = sizeof(from);
	    tolen   = sizeof(to);
	    
	    memset(&msgh, 0, sizeof(struct msghdr));
	    iov.iov_base = buf->start;
	    iov.iov_len  = buf->len;
	    msgh.msg_control = cbuf;
	    msgh.msg_controllen = sizeof(cbuf);
	    msgh.msg_name = &from;
	    msgh.msg_namelen = fromlen;
	    msgh.msg_iov  = &iov;
	    msgh.msg_iovlen = 1;
	    msgh.msg_flags = 0;
	    
	    /* Receive one packet. */
	    recvsize = recvmsg(server_socket, &msgh, 0);

            if (recvsize < MIN_PAYLOAD_HDR_LEN)
            {
                if (recvsize < 0)
                {
                    if (errno != EAGAIN)
                        l2tp_log (LOG_WARNING,
                             "%s: recvfrom returned error %d (%s)\n",
                             __FUNCTION__, errno, strerror (errno));
                }
                else
                {
                    l2tp_log (LOG_WARNING, "%s: received too small a packet\n",
                         __FUNCTION__);
                }
		continue;
            }


	    refme=refhim=0;

	    /* extract IPsec info out */
	    if(gconfig.ipsecsaref) {
		    struct cmsghdr *cmsg;
		    /* Process auxiliary received data in msgh */
		    for (cmsg = CMSG_FIRSTHDR(&msgh);
			 cmsg != NULL;
			 cmsg = CMSG_NXTHDR(&msgh,cmsg)) {
			    if (cmsg->cmsg_level == IPPROTO_IP
				&& cmsg->cmsg_type == IP_IPSEC_REFINFO) {
				    unsigned int *refp;
				    
				    refp = (unsigned int *)CMSG_DATA(cmsg);
				    refme =refp[0];
				    refhim=refp[1];
			    }
		    }
	    }

	    /*
	     * some logic could be added here to verify that we only
	     * get L2TP packets inside of IPsec, or to provide different
	     * classes of service to packets not inside of IPsec.
	     */
	    buf->len = recvsize;
	    fix_hdr (buf->start);
	    extract (buf->start, &tunnel, &call);

	    if (gconfig.debug_network)
	    {
		l2tp_log(LOG_DEBUG, "%s: recv packet from %s, size = %d, "
			 "tunnel = %d, call = %d ref=%u refhim=%u\n",
			 __FUNCTION__, inet_ntoa (from.sin_addr),
			 recvsize, tunnel, call, refme, refhim);
	    }

	    if (gconfig.packet_dump)
	    {
		do_packet_dump (buf);
	    }
	    if (!
		(c = get_call (tunnel, call, from.sin_addr.s_addr,
			       from.sin_port, refme, refhim)))
	    {
		if ((c =
		     get_tunnel (tunnel, from.sin_addr.s_addr,
				 from.sin_port)))
		{
		    /*
		     * It is theoretically possible that we could be sent
		     * a control message (say a StopCCN) on a call that we
		     * have already closed or some such nonsense.  To
		     * prevent this from closing the tunnel, if we get a
		     * call on a valid tunnel, but not with a valid CID,
		     * we'll just send a ZLB to ack receiving the packet.
		     */
		    if (gconfig.debug_tunnel)
			l2tp_log (LOG_DEBUG,
				  "%s: no such call %d on tunnel %d.  Sending special ZLB\n",
				  __FUNCTION__);
		    handle_special (buf, c, call);

		    /* get a new buffer */
		    buf = new_buf (MAX_RECV_SIZE);
		}
		else
		    l2tp_log (LOG_DEBUG,
			      "%s: unable to find call or tunnel to handle packet.  call = %d, tunnel = %d Dumping.\n",
			      __FUNCTION__, call, tunnel);
		
	    }
	    else
	    {
		buf->peer = from;
		/* Handle the packet */
		c->container->chal_us.vector = NULL;
		if (handle_packet (buf, c->container, c))
		{
		    if (gconfig.debug_tunnel)
			l2tp_log (LOG_DEBUG, "%s: bad packet\n", __FUNCTION__);
		};
		if (c->cnu)
		{
		    /* Send Zero Byte Packet */
		    control_zlb (buf, c->container, c);
		    c->cnu = 0;
		}
	    };
	}

	/*
	 * finished obvious sources, look for data from PPP connections.
	 */
	st = tunnels.head;
        while (st)
        {
            sc = st->call_head;
            while (sc)
            {
                if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds))
                {
                    /* Got some payload to send */
                    int result;
                    recycle_payload (buf, sc->container->peer);
/*
#ifdef DEBUG_FLOW_MORE
                    l2tp_log (LOG_DEBUG, "%s: rws = %d, pSs = %d, pLr = %d\n",
                         __FUNCTION__, sc->rws, sc->pSs, sc->pLr);
#endif
		    if ((sc->rws>0) && (sc->pSs > sc->pLr + sc->rws) && !sc->rbit) {
#ifdef DEBUG_FLOW
						log(LOG_DEBUG, "%s: throttling payload (call = %d, tunnel = %d, Lr = %d, Ss = %d, rws = %d)!\n",__FUNCTION__,
								 sc->cid, sc->container->tid, sc->pLr, sc->pSs, sc->rws); 
#endif
						sc->throttle = -1;
						We unthrottle in handle_packet if we get a payload packet, 
						valid or ZLB, but we also schedule a dethrottle in which
						case the R-bit will be set
						FIXME: Rate Adaptive timeout? 						
						tv.tv_sec = 2;
						tv.tv_usec = 0;
						sc->dethrottle = schedule(tv, dethrottle, sc); 					
					} else */
/*					while ((result=read_packet(buf,sc->fd,sc->frame & SYNC_FRAMING))>0) { */
                    while ((result =
                            read_packet (buf, sc->fd, SYNC_FRAMING)) > 0)
                    {
                        add_payload_hdr (sc->container, sc, buf);
                        if (gconfig.packet_dump)
                        {
                            do_packet_dump (buf);
                        }


                        sc->prx = sc->data_rec_seq_num;
                        if (sc->zlb_xmit)
                        {
                            deschedule (sc->zlb_xmit);
                            sc->zlb_xmit = NULL;
                        }
                        sc->tx_bytes += buf->len;
                        sc->tx_pkts++;
                        udp_xmit (buf, st);
                        recycle_payload (buf, sc->container->peer);
                    }
                    if (result != 0)
                    {
                        l2tp_log (LOG_WARNING,
                             "%s: tossing read packet, error = %s (%d).  Closing call.\n",
                             __FUNCTION__, strerror (-result), -result);
                        strcpy (sc->errormsg, strerror (-result));
                        sc->needclose = -1;
                    }
                }
                sc = sc->next;
            }
            st = st->next;
        }
    }

}
void
snd_midi_process_event(struct snd_midi_op *ops,
                       struct snd_seq_event *ev,
                       struct snd_midi_channel_set *chanset)
{
    struct snd_midi_channel *chan;
    void *drv;
    int dest_channel = 0;

    if (ev == NULL || chanset == NULL) {
        snd_printd("ev or chanbase NULL (snd_midi_process_event)\n");
        return;
    }
    if (chanset->channels == NULL)
        return;

    if (snd_seq_ev_is_channel_type(ev)) {
        dest_channel = ev->data.note.channel;
        if (dest_channel >= chanset->max_channels) {
            snd_printd("dest channel is %d, max is %d\n",
                       dest_channel, chanset->max_channels);
            return;
        }
    }

    chan = chanset->channels + dest_channel;
    drv  = chanset->private_data;


    if (ev->type == SNDRV_SEQ_EVENT_NOTE)
        return;

    if (ev->type == SNDRV_SEQ_EVENT_NOTEON && ev->data.note.velocity == 0)
        ev->type = SNDRV_SEQ_EVENT_NOTEOFF;


    if (ev->type == SNDRV_SEQ_EVENT_NOTEON ||
            ev->type == SNDRV_SEQ_EVENT_NOTEOFF ||
            ev->type == SNDRV_SEQ_EVENT_KEYPRESS) {
        if (ev->data.note.note >= 128)
            return;
    }

    switch (ev->type) {
    case SNDRV_SEQ_EVENT_NOTEON:
        if (chan->note[ev->data.note.note] & SNDRV_MIDI_NOTE_ON) {
            if (ops->note_off)
                ops->note_off(drv, ev->data.note.note, 0, chan);
        }
        chan->note[ev->data.note.note] = SNDRV_MIDI_NOTE_ON;
        if (ops->note_on)
            ops->note_on(drv, ev->data.note.note, ev->data.note.velocity, chan);
        break;
    case SNDRV_SEQ_EVENT_NOTEOFF:
        if (! (chan->note[ev->data.note.note] & SNDRV_MIDI_NOTE_ON))
            break;
        if (ops->note_off)
            note_off(ops, drv, chan, ev->data.note.note, ev->data.note.velocity);
        break;
    case SNDRV_SEQ_EVENT_KEYPRESS:
        if (ops->key_press)
            ops->key_press(drv, ev->data.note.note, ev->data.note.velocity, chan);
        break;
    case SNDRV_SEQ_EVENT_CONTROLLER:
        do_control(ops, drv, chanset, chan,
                   ev->data.control.param, ev->data.control.value);
        break;
    case SNDRV_SEQ_EVENT_PGMCHANGE:
        chan->midi_program = ev->data.control.value;
        break;
    case SNDRV_SEQ_EVENT_PITCHBEND:
        chan->midi_pitchbend = ev->data.control.value;
        if (ops->control)
            ops->control(drv, MIDI_CTL_PITCHBEND, chan);
        break;
    case SNDRV_SEQ_EVENT_CHANPRESS:
        chan->midi_pressure = ev->data.control.value;
        if (ops->control)
            ops->control(drv, MIDI_CTL_CHAN_PRESSURE, chan);
        break;
    case SNDRV_SEQ_EVENT_CONTROL14:

        if (ev->data.control.param < 32) {

            chan->control[ev->data.control.param + 32] =
                ev->data.control.value & 0x7f;
            do_control(ops, drv, chanset, chan,
                       ev->data.control.param,
                       ((ev->data.control.value>>7) & 0x7f));
        } else
Example #8
0
void network_thread ()
{
    /*
     * We loop forever waiting on either data from the ppp drivers or from
     * our network socket.  Control handling is no longer done here.
     */
    int fromlen;                /* Length of the address */
    int tunnel, call;           /* Tunnel and call */
    int recvsize;               /* Length of data received */
    struct buffer *buf;         /* Payload buffer */
    struct call *c, *sc;        /* Call to send this off to */
    struct tunnel *st;          /* Tunnel */
    fd_set readfds;             /* Descriptors to watch for reading */
    int max;                    /* Highest fd */
    struct timeval tv;          /* Timeout for select */
    /* This one buffer can be recycled for everything except control packets */
    buf = new_buf (MAX_RECV_SIZE);

gconfig.debug_tunnel = 1;
    for (;;)
    {
        max = build_fdset (&readfds);
        tv.tv_sec = 1;
        tv.tv_usec = 0;
        schedule_unlock ();
        select (max + 1, &readfds, NULL, NULL, NULL);
        schedule_lock ();
        if (FD_ISSET (control_fd, &readfds))
        {
            do_control ();
        }
        if (FD_ISSET (server_socket, &readfds))
        {
            /*
             * Okay, now we're ready for reading and processing new data.
             */
            recycle_buf (buf);
            /* Reserve space for expanding payload packet headers */
            buf->start += PAYLOAD_BUF;
            buf->len -= PAYLOAD_BUF;
            fromlen = sizeof (from);
            recvsize =
                recvfrom (server_socket, buf->start, buf->len, 0,
                          (struct sockaddr *) &from, &fromlen);
            if (recvsize < MIN_PAYLOAD_HDR_LEN)
            {
                if (recvsize < 0)
                {
                    if (errno != EAGAIN)
                        log (LOG_WARN,
                             "%s: recvfrom returned error %d (%s)\n",
                             __FUNCTION__, errno, strerror (errno));
                }
                else
                {
                    log (LOG_WARN, "%s: received too small a packet\n",
                         __FUNCTION__);
                }
            }
            else
            {
                buf->len = recvsize;
                if (gconfig.debug_network)
                {
                    log (LOG_DEBUG, "%s: recv packet from %s, size = %d, "
							"tunnel = %d, call = %d\n", __FUNCTION__,
							inet_ntoa (from.sin_addr), recvsize, tunnel, call);
                }
                if (gconfig.packet_dump)
                {
                    do_packet_dump (buf);
                }
                fix_hdr (buf->start);
                extract (buf->start, &tunnel, &call);
                if (!
                    (c =
                     get_call (tunnel, call, from.sin_addr.s_addr,
                               from.sin_port)))
                {
        log(LOG_DEBUG, "%s(%d)\n", __FUNCTION__,__LINE__);
                    if ((c =
                         get_tunnel (tunnel, from.sin_addr.s_addr,
                                     from.sin_port)))
                    {
                        /*
                         * It is theoretically possible that we could be sent
                         * a control message (say a StopCCN) on a call that we
                         * have already closed or some such nonsense.  To prevent
                         * this from closing the tunnel, if we get a call on a valid
                         * tunnel, but not with a valid CID, we'll just send a ZLB
                         * to ack receiving the packet.
                         */
                        if (gconfig.debug_tunnel)
                            log (LOG_DEBUG,
                                 "%s: no such call %d on tunnel %d.  Sending special ZLB\n",
                                 __FUNCTION__);
                        handle_special (buf, c, call);
                    }
                    else
                        log (LOG_DEBUG,
                             "%s: unable to find call or tunnel to handle packet.  call = %d, tunnel = %d Dumping.\n",
                             __FUNCTION__, call, tunnel);

                }
                else
                {

                    buf->peer = from;
                    /* Handle the packet */
                    c->container->chal_us.vector = NULL;

                    if (handle_packet (buf, c->container, c))
                    {
                        if (gconfig.debug_tunnel)
                            log (LOG_DEBUG, "%s(%d): bad packet\n", __FUNCTION__,__LINE__);
                    };
                    if (c->cnu)
                    {
                        /* Send Zero Byte Packet */
                        control_zlb (buf, c->container, c);
                        c->cnu = 0;
                    }
                }
            }
        };

        st = tunnels.head;

        while (st)
        {
            sc = st->call_head;
            while (sc)
            {
                if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds))
                {
                    /* Got some payload to send */
                    int result;
                    recycle_payload (buf, sc->container->peer);
#ifdef DEBUG_FLOW_MORE
                    log (LOG_DEBUG, "%s: rws = %d, pSs = %d, pLr = %d\n",
                         __FUNCTION__, sc->rws, sc->pSs, sc->pLr);
#endif
/*					if ((sc->rws>0) && (sc->pSs > sc->pLr + sc->rws) && !sc->rbit) {
#ifdef DEBUG_FLOW
						log(LOG_DEBUG, "%s: throttling payload (call = %d, tunnel = %d, Lr = %d, Ss = %d, rws = %d)!\n",__FUNCTION__,
								 sc->cid, sc->container->tid, sc->pLr, sc->pSs, sc->rws);
#endif
						sc->throttle = -1;
						We unthrottle in handle_packet if we get a payload packet,
						valid or ZLB, but we also schedule a dethrottle in which
						case the R-bit will be set
						FIXME: Rate Adaptive timeout?
						tv.tv_sec = 2;
						tv.tv_usec = 0;
						sc->dethrottle = schedule(tv, dethrottle, sc);
					} else */
/*					while ((result=read_packet(buf,sc->fd,sc->frame & SYNC_FRAMING))>0) { */
                    while ((result =
                            read_packet (buf, sc->fd, SYNC_FRAMING)) > 0)
                    {
                        add_payload_hdr (sc->container, sc, buf);
                        if (gconfig.packet_dump)
                        {
                            do_packet_dump (buf);
                        }


                        sc->prx = sc->data_rec_seq_num;
                        if (sc->zlb_xmit)
                        {
                            deschedule (sc->zlb_xmit);
                            sc->zlb_xmit = NULL;
                        }
                        sc->tx_bytes += buf->len;
                        sc->tx_pkts++;
                        udp_xmit (buf);
                        recycle_payload (buf, sc->container->peer);
                    }
                    if (result != 0)
                    {
                        log (LOG_WARN,
                             "%s: tossing read packet, error = %s (%d).  Closing call.\n",
                             __FUNCTION__, strerror (-result), -result);
                        strcpy (sc->errormsg, strerror (-result));
                        sc->needclose = -1;
                    }
                }
                sc = sc->next;
            }
            st = st->next;
        }
    }

}
Example #9
0
/*
 * Process an event in a driver independent way.  This means dealing
 * with RPN, NRPN, SysEx etc that are defined for common midi applications
 * such as GM, GS and XG.
 * There modes that this module will run in are:
 *   Generic MIDI - no interpretation at all, it will just save current values
 *                  of controllers etc.
 *   GM - You can use all gm_ prefixed elements of chan.  Controls, RPN, NRPN,
 *        SysEx will be interpreded as defined in General Midi.
 *   GS - You can use all gs_ prefixed elements of chan. Codes for GS will be
 *        interpreted.
 *   XG - You can use all xg_ prefixed elements of chan.  Codes for XG will
 *        be interpreted.
 */
void
snd_midi_process_event(struct snd_midi_op *ops,
		       struct snd_seq_event *ev,
		       struct snd_midi_channel_set *chanset)
{
	struct snd_midi_channel *chan;
	void *drv;
	int dest_channel = 0;

	if (ev == NULL || chanset == NULL) {
		pr_debug("ALSA: seq_midi_emul: ev or chanbase NULL (snd_midi_process_event)\n");
		return;
	}
	if (chanset->channels == NULL)
		return;

	if (snd_seq_ev_is_channel_type(ev)) {
		dest_channel = ev->data.note.channel;
		if (dest_channel >= chanset->max_channels) {
			pr_debug("ALSA: seq_midi_emul: dest channel is %d, max is %d\n",
				   dest_channel, chanset->max_channels);
			return;
		}
	}

	chan = chanset->channels + dest_channel;
	drv  = chanset->private_data;

	/* EVENT_NOTE should be processed before queued */
	if (ev->type == SNDRV_SEQ_EVENT_NOTE)
		return;

	/* Make sure that we don't have a note on that should really be
	 * a note off */
	if (ev->type == SNDRV_SEQ_EVENT_NOTEON && ev->data.note.velocity == 0)
		ev->type = SNDRV_SEQ_EVENT_NOTEOFF;

	/* Make sure the note is within array range */
	if (ev->type == SNDRV_SEQ_EVENT_NOTEON ||
	    ev->type == SNDRV_SEQ_EVENT_NOTEOFF ||
	    ev->type == SNDRV_SEQ_EVENT_KEYPRESS) {
		if (ev->data.note.note >= 128)
			return;
	}

	switch (ev->type) {
	case SNDRV_SEQ_EVENT_NOTEON:
		if (chan->note[ev->data.note.note] & SNDRV_MIDI_NOTE_ON) {
			if (ops->note_off)
				ops->note_off(drv, ev->data.note.note, 0, chan);
		}
		chan->note[ev->data.note.note] = SNDRV_MIDI_NOTE_ON;
		if (ops->note_on)
			ops->note_on(drv, ev->data.note.note, ev->data.note.velocity, chan);
		break;
	case SNDRV_SEQ_EVENT_NOTEOFF:
		if (! (chan->note[ev->data.note.note] & SNDRV_MIDI_NOTE_ON))
			break;
		if (ops->note_off)
			note_off(ops, drv, chan, ev->data.note.note, ev->data.note.velocity);
		break;
	case SNDRV_SEQ_EVENT_KEYPRESS:
		if (ops->key_press)
			ops->key_press(drv, ev->data.note.note, ev->data.note.velocity, chan);
		break;
	case SNDRV_SEQ_EVENT_CONTROLLER:
		do_control(ops, drv, chanset, chan,
			   ev->data.control.param, ev->data.control.value);
		break;
	case SNDRV_SEQ_EVENT_PGMCHANGE:
		chan->midi_program = ev->data.control.value;
		break;
	case SNDRV_SEQ_EVENT_PITCHBEND:
		chan->midi_pitchbend = ev->data.control.value;
		if (ops->control)
			ops->control(drv, MIDI_CTL_PITCHBEND, chan);
		break;
	case SNDRV_SEQ_EVENT_CHANPRESS:
		chan->midi_pressure = ev->data.control.value;
		if (ops->control)
			ops->control(drv, MIDI_CTL_CHAN_PRESSURE, chan);
		break;
	case SNDRV_SEQ_EVENT_CONTROL14:
		/* Best guess is that this is any of the 14 bit controller values */
		if (ev->data.control.param < 32) {
			/* set low part first */
			chan->control[ev->data.control.param + 32] =
				ev->data.control.value & 0x7f;
			do_control(ops, drv, chanset, chan,
				   ev->data.control.param,
				   ((ev->data.control.value>>7) & 0x7f));
		} else
Example #10
0
size_t vterm_input_write(VTerm *vt, const char *bytes, size_t len)
{
  size_t pos = 0;
  const char *string_start;

  switch(vt->parser.state) {
  case NORMAL:
  case CSI_LEADER:
  case CSI_ARGS:
  case CSI_INTERMED:
  case ESC:
    string_start = NULL;
    break;
  case STRING:
  case ESC_IN_STRING:
    string_start = bytes;
    break;
  }

#define ENTER_STRING_STATE(st) do { vt->parser.state = STRING; string_start = bytes + pos + 1; } while(0)
#define ENTER_STATE(st)        do { vt->parser.state = st; string_start = NULL; } while(0)
#define ENTER_NORMAL_STATE()   ENTER_STATE(NORMAL)

  for( ; pos < len; pos++) {
    unsigned char c = bytes[pos];

    if(c == 0x00 || c == 0x7f) { // NUL, DEL
      if(vt->parser.state >= STRING) {
        more_string(vt, string_start, bytes + pos - string_start);
        string_start = bytes + pos + 1;
      }
      continue;
    }
    if(c == 0x18 || c == 0x1a) { // CAN, SUB
      ENTER_NORMAL_STATE();
      continue;
    }
    else if(c == 0x1b) { // ESC
      vt->parser.intermedlen = 0;
      if(vt->parser.state == STRING)
        vt->parser.state = ESC_IN_STRING;
      else
        ENTER_STATE(ESC);
      continue;
    }
    else if(c == 0x07 &&  // BEL, can stand for ST in OSC or DCS state
            vt->parser.state == STRING) {
      // fallthrough
    }
    else if(c < 0x20) { // other C0
      if(vt->parser.state >= STRING)
        more_string(vt, string_start, bytes + pos - string_start);
      do_control(vt, c);
      if(vt->parser.state >= STRING)
        string_start = bytes + pos + 1;
      continue;
    }
    // else fallthrough

    switch(vt->parser.state) {
    case ESC_IN_STRING:
      if(c == 0x5c) { // ST
        vt->parser.state = STRING;
        done_string(vt, string_start, bytes + pos - string_start - 1);
        ENTER_NORMAL_STATE();
        break;
      }
      vt->parser.state = ESC;
      // else fallthrough

    case ESC:
      switch(c) {
      case 0x50: // DCS
        start_string(vt, VTERM_PARSER_DCS);
        ENTER_STRING_STATE();
        break;
      case 0x5b: // CSI
        vt->parser.csi_leaderlen = 0;
        ENTER_STATE(CSI_LEADER);
        break;
      case 0x5d: // OSC
        start_string(vt, VTERM_PARSER_OSC);
        ENTER_STRING_STATE();
        break;
      default:
        if(is_intermed(c)) {
          if(vt->parser.intermedlen < INTERMED_MAX-1)
            vt->parser.intermed[vt->parser.intermedlen++] = c;
        }
        else if(!vt->parser.intermedlen && c >= 0x40 && c < 0x60) {
          do_control(vt, c + 0x40);
          ENTER_NORMAL_STATE();
        }
        else if(c >= 0x30 && c < 0x7f) {
          do_escape(vt, c);
          ENTER_NORMAL_STATE();
        }
        else {
          DEBUG_LOG("TODO: Unhandled byte %02x in Escape\n", c);
        }
      }
      break;

    case CSI_LEADER:
      /* Extract leader bytes 0x3c to 0x3f */
      if(c >= 0x3c && c <= 0x3f) {
        if(vt->parser.csi_leaderlen < CSI_LEADER_MAX-1)
          vt->parser.csi_leader[vt->parser.csi_leaderlen++] = c;
        break;
      }

      /* else fallthrough */
      vt->parser.csi_leader[vt->parser.csi_leaderlen] = 0;

      vt->parser.csi_argi = 0;
      vt->parser.csi_args[0] = CSI_ARG_MISSING;
      vt->parser.state = CSI_ARGS;

      /* fallthrough */
    case CSI_ARGS:
      /* Numerical value of argument */
      if(c >= '0' && c <= '9') {
        if(vt->parser.csi_args[vt->parser.csi_argi] == CSI_ARG_MISSING)
          vt->parser.csi_args[vt->parser.csi_argi] = 0;
        vt->parser.csi_args[vt->parser.csi_argi] *= 10;
        vt->parser.csi_args[vt->parser.csi_argi] += c - '0';
        break;
      }
      if(c == ':') {
        vt->parser.csi_args[vt->parser.csi_argi] |= CSI_ARG_FLAG_MORE;
        c = ';';
      }
      if(c == ';') {
        vt->parser.csi_argi++;
        vt->parser.csi_args[vt->parser.csi_argi] = CSI_ARG_MISSING;
        break;
      }

      /* else fallthrough */
      vt->parser.csi_argi++;
      vt->parser.intermedlen = 0;
      vt->parser.state = CSI_INTERMED;
    case CSI_INTERMED:
      if(is_intermed(c)) {
        if(vt->parser.intermedlen < INTERMED_MAX-1)
          vt->parser.intermed[vt->parser.intermedlen++] = c;
        break;
      }
      else if(c == 0x1b) {
        /* ESC in CSI cancels */
      }
      else if(c >= 0x40 && c <= 0x7e) {
        vt->parser.intermed[vt->parser.intermedlen] = 0;
        do_csi(vt, c);
      }
      /* else was invalid CSI */

      ENTER_NORMAL_STATE();
      break;

    case STRING:
      if(c == 0x07 || (c == 0x9c && !vt->mode.utf8)) {
        done_string(vt, string_start, bytes + pos - string_start);
        ENTER_NORMAL_STATE();
      }
      break;

    case NORMAL:
      if(c >= 0x80 && c < 0xa0 && !vt->mode.utf8) {
        switch(c) {
        case 0x90: // DCS
          start_string(vt, VTERM_PARSER_DCS);
          ENTER_STRING_STATE();
          break;
        case 0x9b: // CSI
          ENTER_STATE(CSI_LEADER);
          break;
        case 0x9d: // OSC
          start_string(vt, VTERM_PARSER_OSC);
          ENTER_STRING_STATE();
          break;
        default:
          do_control(vt, c);
          break;
        }
      }
      else {
        size_t eaten = 0;
        if(vt->parser.callbacks && vt->parser.callbacks->text)
          eaten = (*vt->parser.callbacks->text)(bytes + pos, len - pos, vt->parser.cbdata);

        if(!eaten) {
          DEBUG_LOG("libvterm: Text callback did not consume any input\n");
          /* force it to make progress */
          eaten = 1;
        }

        pos += (eaten - 1); // we'll ++ it again in a moment
      }
      break;
    }
  }

  return len;
}
Example #11
0
void vterm_push_bytes(VTerm *vt, const char *bytes, size_t len)
{
  size_t pos = 0;
  const char *string_start;

  switch(vt->parser_state) {
  case NORMAL:
    string_start = NULL;
    break;
  case ESC:
  case ESC_IN_OSC:
  case ESC_IN_DCS:
  case CSI:
  case OSC:
  case DCS:
    string_start = bytes;
    break;
  }

#define ENTER_STRING_STATE(st) do { vt->parser_state = st; string_start = bytes + pos + 1; } while(0)
#define ENTER_NORMAL_STATE()   do { vt->parser_state = NORMAL; string_start = NULL; } while(0)

  for( ; pos < len; pos++) {
    unsigned char c = bytes[pos];

    if(c == 0x00 || c == 0x7f) { // NUL, DEL
      if(vt->parser_state != NORMAL) {
        append_strbuffer(vt, string_start, bytes + pos - string_start);
        string_start = bytes + pos + 1;
      }
      continue;
    }
    if(c == 0x18 || c == 0x1a) { // CAN, SUB
      ENTER_NORMAL_STATE();
      continue;
    }
    else if(c == 0x1b) { // ESC
      if(vt->parser_state == OSC)
        vt->parser_state = ESC_IN_OSC;
      else if(vt->parser_state == DCS)
        vt->parser_state = ESC_IN_DCS;
      else
        ENTER_STRING_STATE(ESC);
      continue;
    }
    else if(c == 0x07 &&  // BEL, can stand for ST in OSC or DCS state
            (vt->parser_state == OSC || vt->parser_state == DCS)) {
      // fallthrough
    }
    else if(c < 0x20) { // other C0
      if(vt->parser_state != NORMAL)
        append_strbuffer(vt, string_start, bytes + pos - string_start);
      do_control(vt, c);
      if(vt->parser_state != NORMAL)
        string_start = bytes + pos + 1;
      continue;
    }
    // else fallthrough

    switch(vt->parser_state) {
    case ESC_IN_OSC:
    case ESC_IN_DCS:
      if(c == 0x5c) { // ST
        switch(vt->parser_state) {
          case ESC_IN_OSC: vt->parser_state = OSC; break;
          case ESC_IN_DCS: vt->parser_state = DCS; break;
          default: break;
        }
        do_string(vt, string_start, bytes + pos - string_start - 1);
        ENTER_NORMAL_STATE();
        break;
      }
      vt->parser_state = ESC;
      string_start = bytes + pos;
      // else fallthrough

    case ESC:
      switch(c) {
      case 0x50: // DCS
        ENTER_STRING_STATE(DCS);
        break;
      case 0x5b: // CSI
        ENTER_STRING_STATE(CSI);
        break;
      case 0x5d: // OSC
        ENTER_STRING_STATE(OSC);
        break;
      default:
        if(c >= 0x30 && c < 0x7f) {
          /* +1 to pos because we want to include this command byte as well */
          do_string(vt, string_start, bytes + pos - string_start + 1);
          ENTER_NORMAL_STATE();
        }
        else if(c >= 0x20 && c < 0x30) {
          /* intermediate byte */
        }
        else {
          fprintf(stderr, "TODO: Unhandled byte %02x in Escape\n", c);
        }
      }
      break;

    case CSI:
      if(c >= 0x40 && c <= 0x7f) {
        /* +1 to pos because we want to include this command byte as well */

        do_string(vt, string_start, bytes + pos - string_start + 1);
        ENTER_NORMAL_STATE();
      }
      break;

    case OSC:
    case DCS:
      if(c == 0x07 || (c == 0x9c && !vt->is_utf8)) {
        do_string(vt, string_start, bytes + pos - string_start);
        ENTER_NORMAL_STATE();
      }
      break;

    case NORMAL:
      if(c >= 0x80 && c < 0xa0 && !vt->is_utf8) {
        switch(c) {
        case 0x90: // DCS
          ENTER_STRING_STATE(DCS);
          break;
        case 0x9b: // CSI
          ENTER_STRING_STATE(CSI);
          break;
        case 0x9d: // OSC
          ENTER_STRING_STATE(OSC);
          break;
        default:
          do_control(vt, c);
          break;
        }
      }
      else {
        size_t text_eaten = do_string(vt, bytes + pos, len - pos);

        if(text_eaten == 0) {
          string_start = bytes + pos;
          goto pause;
        }

        pos += (text_eaten - 1); // we'll ++ it again in a moment
      }
      break;
    }
  }

pause:
  if(string_start && string_start < len + bytes) {
    size_t remaining = len - (string_start - bytes);
    append_strbuffer(vt, string_start, remaining);
  }
}
Example #12
0
static size_t do_string(VTerm *vt, const char *str_frag, size_t len)
{
  if(vt->strbuffer_cur) {
    if(str_frag)
      append_strbuffer(vt, str_frag, len);

    str_frag = vt->strbuffer;
    len = vt->strbuffer_cur;
  }
  else if(!str_frag) {
    fprintf(stderr, "parser.c: TODO: No strbuffer _and_ no final fragment???\n");
    len = 0;
  }

  vt->strbuffer_cur = 0;

  size_t eaten;

  switch(vt->parser_state) {
  case NORMAL:


    if(vt->parser_callbacks && vt->parser_callbacks->text) {
      if((eaten = (*vt->parser_callbacks->text)(str_frag, len, vt->cbdata))) {

        // This is /REALLY/ inconsistant
        if(vt->parser_backup_callbacks && vt->parser_backup_callbacks->text) {
          (*vt->parser_backup_callbacks->text)(str_frag, eaten, vt->cbdata);
        }

        return eaten;
      }
    }


    fprintf(stderr, "libvterm: Unhandled text (%zu chars)\n", len);
    return 0;

  case ESC:
    if(len == 1 && str_frag[0] >= 0x40 && str_frag[0] < 0x60) {
      // C1 emulations using 7bit clean
      // ESC 0x40 == 0x80
      do_control(vt, str_frag[0] + 0x40);
      return 0;
    }
    
    if(vt->parser_backup_callbacks && vt->parser_backup_callbacks->escape)
      (*vt->parser_backup_callbacks->escape)(str_frag, len, vt->cbdata);

    if(vt->parser_callbacks && vt->parser_callbacks->escape)
      if((*vt->parser_callbacks->escape)(str_frag, len, vt->cbdata))
        return 0;

    fprintf(stderr, "libvterm: Unhandled escape ESC 0x%02x\n", str_frag[len-1]);
    return 0;

  case CSI:
    do_string_csi(vt, str_frag, len - 1, str_frag[len - 1]);
    return 0;

  case OSC:
    if(vt->parser_backup_callbacks && vt->parser_backup_callbacks->osc)
      (*vt->parser_backup_callbacks->osc)(str_frag, len, vt->cbdata);

    if(vt->parser_callbacks && vt->parser_callbacks->osc)
      if((*vt->parser_callbacks->osc)(str_frag, len, vt->cbdata))
        return 0;

    fprintf(stderr, "libvterm: Unhandled OSC %.*s\n", (int)len, str_frag);
    return 0;

  case DCS:
    if(vt->parser_callbacks && vt->parser_callbacks->dcs)
      if((*vt->parser_callbacks->dcs)(str_frag, len, vt->cbdata))
        return 0;

    if(vt->parser_backup_callbacks && vt->parser_backup_callbacks->dcs)
      if((*vt->parser_backup_callbacks->dcs)(str_frag, len, vt->cbdata))
				return 0;

    fprintf(stderr, "libvterm: Unhandled DCS %.*s\n", (int)len, str_frag);
    return 0;

  case ESC_IN_OSC:
  case ESC_IN_DCS:
    fprintf(stderr, "libvterm: ARGH! Should never do_string() in ESC_IN_{OSC,DCS}\n");
    return 0;
  }

  return 0;
}
Example #13
0
void network_thread ()
{
    /*
     * We loop forever waiting on either data from the ppp drivers or from
     * our network socket.  Control handling is no longer done here.
     */
    int fromlen;                /* Length of the address */
    int tunnel, call;           /* Tunnel and call */
    int recvsize;               /* Length of data received */
    struct buffer *buf;         /* Payload buffer */
    struct call *c, *sc;        /* Call to send this off to */
    struct tunnel *st;          /* Tunnel */
    fd_set readfds;             /* Descriptors to watch for reading */
    int max;                    /* Highest fd */
    struct timeval tv;          /* Timeout for select */
    /* This one buffer can be recycled for everything except control packets */
    buf = new_buf (MAX_RECV_SIZE);
    for (;;)
    {
        /*
           * First, let's send out any outgoing packets that are waiting on us.
           * xmit_udp should only
           * contain control packets in the unthreaded version!
         */
        max = 0;
        FD_ZERO (&readfds);
        st = tunnels.head;
        while (st)
        {
            if (st->self->needclose ^ st->self->closing)
            {
                if (debug_tunnel)
                    log (LOG_DEBUG, "%S: closing down tunnel %d\n",
                         __FUNCTION__, st->ourtid);
                call_close (st->self);
                /* Reset the while loop
                   and check for NULL */
                st = tunnels.head;
                if (!st)
                    break;
                continue;
            }
            sc = st->call_head;
            while (sc)
            {
                if (sc->needclose ^ sc->closing)
                {
                    call_close (sc);
                    sc = st->call_head;
                    if (!sc)
                        break;
                    continue;
                }
                if (sc->fd > -1)
                {
/*					if (!sc->throttle && !sc->needclose && !sc->closing) { */
                    if (!sc->needclose && !sc->closing)
                    {
                        if (sc->fd > max)
                            max = sc->fd;
                        FD_SET (sc->fd, &readfds);
                    }
                }
                sc = sc->next;
            }
            st = st->next;
        }
        FD_SET (server_socket, &readfds);
        if (server_socket > max)
            max = server_socket;
        FD_SET (control_fd, &readfds);
        if (control_fd > max)
            max = control_fd;
        tv.tv_sec = 1;
        tv.tv_usec = 0;

        /*add start, by MJ.*/
        extern int is_first_run;
        if(is_first_run)
        {
            int lac_fp;  /* to get conn_id which written by acos */
            char cmd[64]={0};
            char conn_id[64] = "c default";            

            lac_fp = fopen("/tmp/l2tp/l2tpd.info", "r");

            if (lac_fp != NULL){
                //fscanf(lac_fp, "%s", conn_id);
                fgets(conn_id, sizeof(conn_id), lac_fp);
                fclose(lac_fp);
            }
            else
                log (LOG_DEBUG, "open /tmp/l2tp/l2tpd.info fialed\n");

            log (LOG_DEBUG, "%s: -> the first run.\n", __FUNCTION__);
            
            sprintf(cmd, "c %s", conn_id);

            //do_control("c MJ.");
            do_control(cmd);
            //write(control_fd, cmd, strlen(cmd) );
            is_first_run = 0;
        }
        /*add end. by MJ.*/        

        schedule_unlock ();
        select (max + 1, &readfds, NULL, NULL, NULL);
        schedule_lock ();

        if (FD_ISSET (control_fd, &readfds))
        {
            do_control (NULL);
        }
        if (FD_ISSET (server_socket, &readfds))
        {
            /*  wklin added start, 04/12/2011 */
            extern void connect_pppunit(void);
            connect_pppunit();
            /*  wklin added end, 04/12/2011 */
            /*
             * Okay, now we're ready for reading and processing new data.
             */
            recycle_buf (buf);
            /* Reserve space for expanding payload packet headers */
            buf->start += PAYLOAD_BUF;
            buf->len -= PAYLOAD_BUF;
            fromlen = sizeof (from);
            recvsize =
                recvfrom (server_socket, buf->start, buf->len, 0,
                          (struct sockaddr *) &from, &fromlen);

            /* , by MJ. for debugging.*/
            //log (LOG_DEBUG, "receive %d bytes from server_scoket.\n", recvsize);


            if (recvsize < MIN_PAYLOAD_HDR_LEN)
            {
                if (recvsize < 0)
                {
                    if (errno != EAGAIN)
                        log (LOG_WARN,
                             "%s: recvfrom returned error %d (%s)\n",
                             __FUNCTION__, errno, strerror (errno));
                }
                else
                {
                    log (LOG_WARN, "%s: received too small a packet\n",
                         __FUNCTION__);
                }
            }
            else
            {
                buf->len = recvsize;
                fix_hdr (buf->start);
                extract (buf->start, &tunnel, &call);
                if (debug_network)
                {
                    log (LOG_DEBUG, "%s: recv packet from %s, size = %d,"
"tunnel = %d, call = %d\n", __FUNCTION__, inet_ntoa (from.sin_addr), recvsize, tunnel, call);
                }
                if (packet_dump)
                {
                    do_packet_dump (buf);
                }
                if (!
                    (c =
                     get_call (tunnel, call, from.sin_addr.s_addr,
                               from.sin_port)))
                {
                    if ((c =
                         get_tunnel (tunnel, from.sin_addr.s_addr,
                                     from.sin_port)))
                    {
                        /*
                         * It is theoretically possible that we could be sent
                         * a control message (say a StopCCN) on a call that we
                         * have already closed or some such nonsense.  To prevent
                         * this from closing the tunnel, if we get a call on a valid
                         * tunnel, but not with a valid CID, we'll just send a ZLB
                         * to ack receiving the packet.
                         */
                        if (debug_tunnel)
                            log (LOG_DEBUG,
                                 "%s: no such call %d on tunnel %d.  Sending special ZLB\n",
                                 __FUNCTION__);
                        handle_special (buf, c, call);
                    }
                    else
                        log (LOG_DEBUG,
                             "%s: unable to find call or tunnel to handle packet.  call = %d, tunnel = %d Dumping.\n",
                             __FUNCTION__, call, tunnel);

                }
                else
                {
                    buf->peer = from;
                    /* Handle the packet */
                    c->container->chal_us.vector = NULL;
                    if (handle_packet (buf, c->container, c))
                    {
                        if (debug_tunnel)
                            log (LOG_DEBUG, "%s: bad packet\n", __FUNCTION__);
                    };
                    if (c->cnu)
                    {
                        /* Send Zero Byte Packet */
                        control_zlb (buf, c->container, c);
                        c->cnu = 0;

                        
    
                    }
                }
            }
        };

        st = tunnels.head;
        while (st)
        {
            sc = st->call_head;
            while (sc)
            {
                if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds))
                {
                    /* Got some payload to send */
                    int result;
                    recycle_payload (buf, sc->container->peer);
#ifdef DEBUG_FLOW_MORE
                    log (LOG_DEBUG, "%s: rws = %d, pSs = %d, pLr = %d\n",
                         __FUNCTION__, sc->rws, sc->pSs, sc->pLr);
#endif
/*					if ((sc->rws>0) && (sc->pSs > sc->pLr + sc->rws) && !sc->rbit) {
#ifdef DEBUG_FLOW
						log(LOG_DEBUG, "%s: throttling payload (call = %d, tunnel = %d, Lr = %d, Ss = %d, rws = %d)!\n",__FUNCTION__,
								 sc->cid, sc->container->tid, sc->pLr, sc->pSs, sc->rws); 
#endif
						sc->throttle = -1;
						We unthrottle in handle_packet if we get a payload packet, 
						valid or ZLB, but we also schedule a dethrottle in which
						case the R-bit will be set
						FIXME: Rate Adaptive timeout? 						
						tv.tv_sec = 2;
						tv.tv_usec = 0;
						sc->dethrottle = schedule(tv, dethrottle, sc); 					
					} else */
/*					while ((result=read_packet(buf,sc->fd,sc->frame & SYNC_FRAMING))>0) { */
                    while ((result =
                            read_packet (buf, sc->fd, SYNC_FRAMING)) > 0)
                    {
                        add_payload_hdr (sc->container, sc, buf);
                        if (packet_dump)
                        {
                            do_packet_dump (buf);
                        }


                        sc->prx = sc->data_rec_seq_num;
                        if (sc->zlb_xmit)
                        {
                            deschedule (sc->zlb_xmit);
                            sc->zlb_xmit = NULL;
                        }
                        sc->tx_bytes += buf->len;
                        sc->tx_pkts++;
                        udp_xmit (buf);
                        recycle_payload (buf, sc->container->peer);
                    }
                    if (result != 0)
                    {
                        log (LOG_WARN,
                             "%s: tossing read packet, error = %s (%d).  Closing call.\n",
                             __FUNCTION__, strerror (-result), -result);
                        strcpy (sc->errormsg, strerror (-result));
                        sc->needclose = -1;
                    }
                }
                sc = sc->next;
            }
            st = st->next;
        }
    }

}
Example #14
0
int
main(int argc, char *argv[])
{
  nextopt_t       nopt = nextopt_INIT(argc, argv, ":hVb:gLq");
  char            opt;
  int             opt_g = 0;
  int             opt_L = 0;
  int             flag_sticky = 0;
  uchar_t         cmd[2] = {'\0', '\0'};

  progname = nextopt_progname(&nopt);
  while((opt = nextopt(&nopt))){
      char optc[2] = {nopt.opt_got, '\0'};
      switch(opt){
      case 'h': usage(); die(0); break;
      case 'V': version(); die(0); break;
      case 'b': basedir = nopt.opt_arg; break;
      case 'g': ++opt_g; break;
      case 'L': ++opt_L; break;
      case 'q': ++opt_q; break;
      case ':':
          fatal_usage("missing argument for option -", optc);
          break;
      case '?':
          if(nopt.opt_got != '?'){
              fatal_usage("invalid option: -", optc);
          }
          /* else fallthrough: */
      default :
          die_usage(); break;
      }
  }

  argc -= nopt.arg_ndx;
  argv += nopt.arg_ndx;
  if(!*argv){
      eputs(progname, ": usage error: missing arguments");
      die_usage();
  }

  /* next argv is the control command (can be taken from first letter): */
  switch(cmd[0] = *argv[0]){
  case 'A': flag_sticky = +1; break;
  case 'X': flag_sticky = -1; break;
  case 'd':
  case 'u':
  case 'o':
  case 'p':
  case 'c':
  case 'a':
  case 'h':
  case 'i':
  case 'k':
  case 'q':
  case 't':
  case 'w':
  case '1':
  case '2':
      if(opt_L){
         /* control command for log service: */
         cmd[1] |= SVCMD_FLAG_LOG;
      }
      break;
  case 'D':
  case 'U':
      if(opt_L){
          fatal_usage("meta-command '", *argv,
                      "' may not be used with option -L");
      }
      break;
  default:
      fatal_usage("unknown control command '", *argv, "'");
      break;
  }

  --argc;
  ++argv;
  if(!*argv){
      fatal_usage("missing argument: no service(s) specified");
  }

  if(basedir == NULL)
      basedir = getenv("PERP_BASE");
  if((basedir == NULL) || (basedir[0] == '\0'))
      basedir = ".";

  if(chdir(basedir) != 0){
      fatal_syserr("unable to chdir() to ", basedir);
  }

  /*
  ** service activation/deactivation command (A or X):
  */
  if(flag_sticky != 0){
      do_sticky(flag_sticky, argv);
      die((errs ? 111 : 0));
  }

  /*
  ** else: service control command
  */

  /* killpg() flag: */
  if(opt_g){
      cmd[1] |= SVCMD_FLAG_KILLPG;
  }

  do_control(cmd, argv);

  die((errs ? 111 : 0));
}