Esempio n. 1
0
void parse_descriptor(void) {
  switch((SWAPENDIAN(pSetupPacket->wValue) & HI_BYTE) >> 8) {
  case DESCR_TYPE_DEVICE:
    descrbuffer = (uint8*)&(DeviceDescriptor);
    cbuff_tail = 0;
    if(SWAPENDIAN(pSetupPacket->wLength) < DeviceDescriptor.bLength)
      cbuff_head =SWAPENDIAN(pSetupPacket->wLength);
    else
      cbuff_head = DeviceDescriptor.bLength;
    send_config();
    break;

  case DESCR_TYPE_CONFIGURATION:
    descrbuffer = (uint8*)&(ConfigurationDescriptor);
    cbuff_tail = 0;			
    if(SWAPENDIAN(pSetupPacket->wLength) < sizeof(FULL_CONFIG))
      cbuff_head = SWAPENDIAN(pSetupPacket->wLength);
    else
      cbuff_head = sizeof(FULL_CONFIG);
    send_config();
    break;

  case DESCR_TYPE_STRING:
    switch(SWAPENDIAN(pSetupPacket->wValue) & LO_BYTE) {
    case STDENDPREQ_LANG:
      descrbuffer = (uint8*)&(LangDescriptor);
      cbuff_tail = 0;				
      if(SWAPENDIAN(pSetupPacket->wLength) < sizeof(LANG_DESCR))
        cbuff_head = SWAPENDIAN(pSetupPacket->wLength);
      else
        cbuff_head = LangDescriptor.bLength;
      send_config();
      break;
    case STDENDPREQ_PRODUCT:
      descrbuffer = (uint8*)&(DevStringDescriptor);
      cbuff_tail = 0;
      if(SWAPENDIAN(pSetupPacket->wLength) < sizeof(DEVSTRING_DESCR))
        cbuff_head = SWAPENDIAN(pSetupPacket->wLength);
      else
        cbuff_head = DevStringDescriptor.bLength;
      send_config();
      break;
				
    case STDENDPREQ_MANUF:
      descrbuffer = (uint8*)&(ManufStringDescriptor);
      cbuff_tail = 0;
      if(SWAPENDIAN(pSetupPacket->wLength) < sizeof(MANUFSTRING_DESCR))
        cbuff_head = SWAPENDIAN(pSetupPacket->wLength);
      else
        cbuff_head = ManufStringDescriptor.bLength;
      send_config();
      break;
					
    default:
      stall();
      break;
    }
  }
}
void lcd_goto(unsigned char data)
{
 	if(data<16)
	{
	 	send_config(0x80+data);
	}
	else
	{
	 	data=data-20;
		send_config(0xc0+data);
	}
}
Esempio n. 3
0
void lcd_goto(unsigned char data)		//set the location of the lcd cursor
{										//if the given value is (0-15) the 
 	if(data<16)							//cursor will be at the upper line
	{									//if the given value is (20-35) the 
	 	send_config(0x80+data);			//cursor will be at the lower line
	}									//location of the lcd cursor(2X16):
	else								// -----------------------------------------------------
	{									// | |00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15| |
	 	data=data-20;					// | |20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35| |
		send_config(0xc0+data);			// -----------------------------------------------------	
	}
}
Esempio n. 4
0
static void reparent(client_t *c, strut_t *s)
{
    XSetWindowAttributes pattr;
    geom_t f;

    f = frame_geom(c);
    pattr.override_redirect = True;
    pattr.background_pixel = bg.pixel;
    pattr.border_pixel = bd.pixel;
    pattr.event_mask = SubMask|ButtonPressMask|ExposureMask|EnterWindowMask;
    c->frame = XCreateWindow(dpy, root, f.x, f.y, f.w, f.h, BW(c),
        DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen),
        CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWEventMask, &pattr);

#ifdef SHAPE
    if (shape) {
        XShapeSelectInput(dpy, c->win, ShapeNotifyMask);
        set_shape(c);
    }
#endif

#ifdef XFT
    c->xftdraw = XftDrawCreate(dpy, (Drawable)c->frame,
        DefaultVisual(dpy, DefaultScreen(dpy)),
        DefaultColormap(dpy, DefaultScreen(dpy)));
#endif

    XAddToSaveSet(dpy, c->win);
    XSelectInput(dpy, c->win, ColormapChangeMask|PropertyChangeMask);
    XSetWindowBorderWidth(dpy, c->win, 0);
    XResizeWindow(dpy, c->win, c->geom.w, c->geom.h);
    XReparentWindow(dpy, c->win, c->frame, 0, frame_height(c));

    send_config(c);
}
Esempio n. 5
0
void hmc5843_periodic(void)
{
  if (!hmc5843.initialized) {
    send_config();
    hmc5843.initialized = TRUE;
  } else if (hmc5843.timeout++ > HMC5843_TIMEOUT && HMC5843_I2C_DEV.status == I2CIdle && i2c_idle(&HMC5843_I2C_DEV)) {
#ifdef USE_HMC59843_ARCH_RESET
    hmc5843_arch_reset();
#endif
    hmc5843.i2c_trans.type = I2CTransTx;
    hmc5843.i2c_trans.len_w = 1;
    hmc5843.i2c_trans.buf[0] = 0x3;
    i2c_submit(&HMC5843_I2C_DEV, &hmc5843.i2c_trans);
    while (hmc5843.i2c_trans.status == I2CTransPending || hmc5843.i2c_trans.status == I2CTransRunning);

    hmc5843.i2c_trans.type = I2CTransRx;
    hmc5843.i2c_trans.len_r = 6;
    i2c_submit(&HMC5843_I2C_DEV, &hmc5843.i2c_trans);
    while (hmc5843.i2c_trans.status == I2CTransPending || hmc5843.i2c_trans.status == I2CTransRunning);
    hmc5843.timeout = 0;
  }

#ifdef HMC5843_NO_IRQ
  // < 50Hz
  fake_mag_eoc = 1;
#endif

}
void lcd_goto(unsigned char data)				//set the location of the lcd cursor
{										
	 	send_config(0x80+data);		
// -----------------------------------------------------
// | |00|01|02|03|04|05|06|07| | 				//1 location can store 2 character
// | |17|18|19|...........|15| |
// | |09|10|11|...........|23| |
// | |24|.................|31| |
// -----------------------------------------------------	
}
Esempio n. 7
0
void hmc5843_periodic(void)
{
    if (!hmc5843.initialized) {
        send_config();
        hmc5843.initialized = TRUE;
    } else if (hmc5843.timeout++ > HMC5843_TIMEOUT) {
        hmc5843_arch_reset();
        hmc5843.timeout = 0;
    }
}
Esempio n. 8
0
static int dev_close(struct sr_dev_inst *sdi)
{
	struct dev_context *devc;

	devc = sdi->priv;
	if (devc->config_dirty)
		/* Some configuration changes were queued up but didn't
		 * get sent to the device, likely because we were never
		 * in acquisition mode. Send them out now. */
		send_config(sdi);

	return std_serial_dev_close(sdi);
}
Esempio n. 9
0
void hmc5843_periodic(void)
{
    if (!hmc5843.initialized) {
        send_config();
        hmc5843.initialized = TRUE;
    } else if (hmc5843.timeout++ > HMC5843_TIMEOUT) {
        hmc5843_arch_reset();
        hmc5843.i2c_trans.type = I2CTransRx;
        hmc5843.i2c_trans.len_r = 7;
        i2c_submit(&i2c2, &hmc5843.i2c_trans);
        hmc5843.reading = TRUE;
        hmc5843.ready_for_read = FALSE;
        hmc5843.timeout = 0;
    }
}
Esempio n. 10
0
void init()
{
	//set I/O input output
	TRISD = 0b00000000;			//configure PORTB I/O direction
	TRISC = 0b00000000;			//configure PORTC I/O direction
	TRISB = 0b00000011;
	TRISA = 0b00111111;			//configure PORTA I/O direction
	
	// ADC configuration	
	ADCON1 = 0b11000011;			//set all portA as Analog Input, right justified	

	//Timer 0 configuration
	T0CON = 0b00000100;			//prescale 1: 32


	// setup for pwm			//For controlling back light
	PR2 = 255;
	T2CON =  	0b00000100;		//prescale 1:
	CCP1CON =	0b00001100;		//Configuration for pwm
	CCP2CON =	0b00001100;

	//configure lcd
	RST = 0;
	RST = 1;
	delay (100000);						
	PSB  = 1;

	//basic instruction config
	send_config(0b00110000);            //function set
	lcd_clr();                          //clear display at lcd
	send_config(0b00000010);            //lcd return to home
	send_config(0b00000110);            //entry mode-cursor increase 1
	send_config(0b00001100);            //display on, cursor off and cursor blink off

	//set initial condition
	send_config(0b00110100);            //extended function set
	send_config(0b00000010);
	send_config(0b00000100);
	send_config(0b00110000);            //function set
	
	lcd_clr();		//clear lcd
	CCPR1L = 50;		//set the brightness of the back lcd

}
Esempio n. 11
0
void datain_endp0(void) {	
  R_UCR0 &= ~TX0E;
  R_UIR2 = TXD0FR;

  if(address != 0) {
    // set the address if we just got address from last OUT
    R_UADDR |= (UADD_MASK & address);
    address = 0;
  }

  // send more data if this is not ack for last packet
  if(last_packet == FALSE) {
    send_config();
    ucr |= TX0E;
    R_UCR0 = ucr;
  } else {
    // this was last packet, reset last packet status
    last_packet = FALSE;
  }
}
Esempio n. 12
0
static void reparent(Client *c)
{
	XSetWindowAttributes p_attr;

	XSelectInput(dpy, c->window, EnterWindowMask | PropertyChangeMask);

	p_attr.override_redirect = True;
	p_attr.background_pixel = bg.pixel;
	p_attr.event_mask = ChildMask | ButtonPressMask | ExposureMask | EnterWindowMask;
	c->parent = XCreateWindow(dpy, root, c->x-c->border, c->y-c->border,
				  c->width+(c->border*2), c->height + (c->border*2), 0,
				  DefaultDepth(dpy, screen), CopyFromParent,
				  DefaultVisual(dpy, screen),
				  CWOverrideRedirect | CWBackPixel | CWEventMask, &p_attr);

	XAddToSaveSet(dpy, c->window);
	XSetWindowBorderWidth(dpy, c->window, 0);
	XReparentWindow(dpy, c->window, c->parent, c->border, c->border);

	send_config(c);
}
Esempio n. 13
0
static int dc_rx_hnd(struct pnet_pack *pack) {
	struct lego_dc_msg *lego_msg;
	int addit_len = 0;
	char *msg;

	msg = pnet_pack_get_data(pack);

	switch (msg[0]) {
		case DEVICE_CONFIG_DATA:
			send_config(msg);
			break;
		case EXECUTE_COMMAND:
			lego_msg = (struct lego_dc_msg *) (msg);
			handle_command(lego_msg, &addit_len, dc_out_msg.body.tail + 1);
			break;
		case REQUEST_SENSOR_DATA:
			break;
	}

	return NET_HND_STOP_FREE;
}
Esempio n. 14
0
/**
  * @brief Main
  * @return Ritorna un intero.
 */
int main(int argc, char *argv[])
{
	
	/* Inizializzazione delle variabili */
	index = 0;
	lPkt = NULL;
	contACK = 0;
	tipoCnt = 0;

	printf ("uso i parametri di default \n%s\n", PARAMETRIDEFAULT );
	localportfrommobile = 6001;
	localportdatamonitor = 7001;
	portmonitor = 8000;
	
	/* Inizializzazione dei vettori */
	initV(cfgPKT);
	initV(tipoConn);
	initV(pktTipoConn);
	
	init_random();

	/* Si connette al monitor */
	ris=TCP_setup_connection(&monitorfd, "127.0.0.1", portmonitor,  300000, 300000, 1);
	if(!ris) {	printf ("TCP_setup_connection() failed\n"); exit(1); }
	else printf("monitorfd %d\n", monitorfd);

	FD_ZERO(&all);
	FD_SET(monitorfd,&all);
	maxfd=monitorfd;

	ris=RecvCfg(monitorfd,&numporte,porte);
	if(!ris) {	printf ("RecvCfg() failed\n"); exit(1); }
	for(i=0;i<numporte;i++) {
		cfgPorte[i]=porte[i];
	}

	/* Creazione del pacchetto della configurazione delle porte */
	config_pkt_porte(cfgPKT, numporte);
	
	ris=UDP_setup_socket_bound( &monitordatafd, localportdatamonitor, 65535, 65535 );
	if (!ris) {	printf ("UDP_setup_socket_bound() failed\n"); exit(1); }
	FD_SET(monitordatafd,&all);
	if(monitordatafd>maxfd)
		maxfd=monitordatafd;

	appmobilefd=0;
	/* Attende la connessione dall'applicazione lato mobile */
	ris=TCP_setup_socket_listening( &listening_mobilefd, localportfrommobile, 300000, 300000, 1);
	if (!ris)
	{	printf ("TCP_setup_socket_listening() failed\n");
		exit(1);
	}
	do { memset (&Cli, 0, sizeof (Cli));		
		len = sizeof (Cli);
		appmobilefd = accept ( listening_mobilefd, (struct sockaddr *) &Cli, &len);
	} while ( (appmobilefd<0) && (errno==EINTR) );
	if (appmobilefd < 0 ) {	
		perror("accept() failed: \n");
		exit (1);
	}
	/* NO NAGLE per i tcp */
	ris=SetsockoptTCPNODELAY(appmobilefd,1); if (!ris) { fprintf(stderr,"unable to setup TCPNODELAY option\n"); exit(5); }
	/* chiusura del socket TCP listening e setup dei socket UDP	*/
	close(listening_mobilefd);
	FD_SET(appmobilefd,&all);
	if(appmobilefd>maxfd)
		maxfd=appmobilefd;
		
	/* Imprime il timestamp sul primo pacchetto, ossia fa partire il cronometro */
	gettimeofday(&timePktFirst,NULL);
	memcpy( (char*)&(tipoConn[0]), (char*)&timePktFirst, sizeof(struct timeval) );
	
	/* Controllo del tipo di connessione */
	for(;;)
	{
		do 
		{
			rdset=all;

#ifdef VICDEBUG
			stampa_fd_set("rdset prima",&rdset);
#endif

			ris=select(maxfd+1,&rdset,NULL,NULL,NULL);
		} while( (ris<0) && (errno==EINTR) );
		if(ris<0) 
		{
			perror("select failed: ");
			exit(1);
		}
			
		/* Controlla se sono arrivati pacchetti dall'applicazione */
		if( FD_ISSET(appmobilefd,&rdset) )
		{
			uint32_t buf[PKTSIZE];
			uint32_t idmsg;	
			struct timeval sent, now, tempoimpiegato;
			long int msec;

			/* riceve un pkt */
			/*ris=Readn(appmobilefd,(char*)buf,PKTSIZE);
			if(ris!=PKTSIZE) { fprintf(stderr,"recv from appmobile failed, received %d: ", ris); exit(9); }*/
			ris=Readn(appmobilefd,(char*)buf,sizeof(buf));
			if(ris!=sizeof(buf)) { fprintf(stderr,"recv from appmobile failed, received %d: ", ris); exit(9); }

			/* Appena arriva un pacchetto dall'AppMobile, calcola quanto tempo è passato */
			memcpy( (char*)&sent, (char*)&(tipoConn[0]), sizeof(struct timeval) );
			gettimeofday(&now,NULL);

			tempoimpiegato=differenza(now,sent);
			msec=(tempoimpiegato.tv_sec*1000)+(tempoimpiegato.tv_usec/1000);
			
			idmsg = buf[0];

			/* ID del pkt di connessione è 42, tanto per cambiare */
			pktTipoConn[0] = 42;
			
			/* Può capitare che arrivi il primo pacchetto con 40msec di delay su connessione LENTA */
			/* Se è il primo pacchetto */
			if(idmsg < 1)
			{
				/* E se il primo pacchetto arriva con abbastanza ritardo, vuol dire che la connessione è LENTA */
				if((msec > DELAY_VELOCE) && (msec < DELAY_MUTA))
				{
					tipoCnt = pktTipoConn[1] = CONN_LENTA;
					break;
				}
				/* Altrimenti sarà MUTA */
				else if(msec >= DELAY_MUTA)
				{
					tipoCnt = pktTipoConn[1] = CONN_MUTA;
					break;
				}
			}
			/* Se invece il secondo pacchetto è veloce, vuol dire che siamo nella VELOCE */
			else if(msec <= DELAY_LENTA)
			{
				tipoCnt = pktTipoConn[1] = CONN_VELOCE;
				break;
			}
			/* Altrimenti è LENTA */
			else
			{
				tipoCnt = pktTipoConn[1] = CONN_LENTA;
				break;
			}

		}
	}
	
		/* Invio il tipo di connessione al Fixed su tutte le porte attive per avvertirlo */
		/* Invio il tipo di connessione su ogni porta attiva per ben due volte (per evitare di gestire i suoi NACK) */
		for(k=0; k<2; k++)
		{
			for(i=0; i<numporte; i++)
			{
				ris = send_udp(monitordatafd, (char*)pktTipoConn, sizeof(pktTipoConn) , 1000, "127.0.0.1", cfgPorte[i]);
				if(!(ris))
				{
					fprintf(stderr,"Errore durante l'invio del tipo di connessione!\n");
				}
			}
		}

	send_config(cfgPKT, monitordatafd, cfgPorte, numporte);
	
	/* Configurazione del LBMobile sul tipo di connessione */
	switch(tipoCnt)
	{
		case CONN_MUTA:
		
#ifdef TIPO_CONN
			fprintf(stdout,ROSSO "\n*** Attivazione della connessione MUTA ***\n" DEFAULTCOLOR "\n");
#endif
			
/* *********************************************** MUTA ************************************************** */

	for(;;)
	{
		do {
			rdset=all;

#ifdef VICDEBUG
			stampa_fd_set("rdset prima",&rdset);
#endif

			ris=select(maxfd+1,&rdset,NULL,NULL,NULL);
		} while( (ris<0) && (errno==EINTR) );
		if(ris<0) {
			perror("select failed: ");
			exit(1);
		}

#ifdef VICDEBUG
		stampa_fd_set("rdset dopo",&rdset);
#endif

		/* Lettura dei pacchetti UDP provenienti dal Monitor */
		if(FD_ISSET(monitordatafd,&rdset))
		{
			lettura_pkt_monitor();		
		}

		/* Lettura dei pacchetti TCP (CONF, ACK, NACK) provenienti dal Monitor */
		if( FD_ISSET(monitorfd,&rdset) )
		{
			char ch; int ris;
			uint32_t tmpnumporte;
			uint16_t tmpporte[MAXNUMCONNECTIONS];
			uint32_t idmsg;

			/* ris=recv(monitorfd,buf,65536,MSG_DONTWAIT); */
			ris=recv(monitorfd,&ch,1,0);
			if(ris!=1) { fprintf(stderr,"recv from monitor failed: "); exit(9); }
			
			if(ch=='C')
			{
				/* Ricezione del nuovo numero di porte attive */
				ris=recv(monitorfd,(char*)&tmpnumporte,sizeof(uint32_t),0);
				if(ris!=sizeof(uint32_t)) { fprintf(stderr,"(C)recv_configurazione failed: "); exit(9); }

				/* Ricezione del nuovo vettore di porte attive */
				for(i=0;i<tmpnumporte;i++)
				{
 					ris=recv(monitorfd,&(tmpporte[i]),sizeof(uint16_t),0);
					if(ris!=sizeof(uint16_t)) { fprintf(stderr,"(C%d)recv_configurazione failed: ",i); exit(9); }
				}
				
				/* Aggiorna l'indice della porta a cui stava inviando i pacchetti col nuovo */
				config_new_porte(cfgPorte, tmpporte);

				setup_new_configurazione(&numporte,porte,&tmpnumporte,tmpporte);

				/* Creazione del pacchetto della configurazione delle porte */
				config_pkt_porte(cfgPKT, numporte);
				
				/* Invio della configurazione al Fixed */
				send_config(cfgPKT, monitordatafd, cfgPorte, numporte);

			} 
			else if( ch=='A' )
			{
				ris=recv(monitorfd,(char*)&idmsg,sizeof(uint32_t),0);
				if(ris!=sizeof(uint32_t)) { fprintf(stderr,"(A)recv ack failed: "); exit(9); }

				/* Se arriva un ACK presente nella lista di pacchetti, lo rimuove */
				if(find_id_pkt(idmsg, lPkt) != NULL)
				{
					lPkt = rim_pkt(idmsg, lPkt);
				}
			} 
			else if( ch=='N' )
			{
				struct listaPKT *list_aux;

				list_aux = NULL;

				ris=recv(monitorfd,(char*)&idmsg,sizeof(uint32_t),0);
				if(ris!=sizeof(uint32_t)) { fprintf(stderr,"(N)recv nack failed: "); exit(9); }

				/* Restituisce il puntatore lista all'elemento interessato */
				list_aux = find_id_pkt(idmsg, lPkt);

				/* Se il pacchetto NACKato è presente nella lista */
				if(list_aux != NULL)
				{
					/* E se la porta da cui è stato inviato il pacchetto è uguale all'attuale da cui s'invia */
					if(list_aux->portaPKT == cfgPorte[index])
					{
						/* Viene cambiata */
						index=(index+1)%numporte;
					}
					/* Aggiorna anche la porta d'invio del pacchetto */
					list_aux->portaPKT = cfgPorte[index];
					
					/* Rispedisce l'esatto pacchetto che è stato NACKato */
					ris=send_udp(monitordatafd, (char*)list_aux->pkt, sizeof(list_aux->pkt) , 1000, "127.0.0.1", cfgPorte[index] );
					if(!(ris))
					{
						fprintf(stderr,"pkt id %u NOT sent\n", list_aux->pkt[0] );
					}
				}
			}

		}
		
		/* Controlla se sono arrivati pacchetti dall'applicazione */
		if( FD_ISSET(appmobilefd,&rdset) )
		{
			lettura_pkt_app();
		}
		
	} /* fine for ;; */
	
/***********************************************************************************************************/

			break;
		case CONN_VELOCE:
				
#ifdef TIPO_CONN
			fprintf(stderr,GREEN "\n*** Attivazione della connessione VELOCE ***\n" DEFAULTCOLOR "\n");
#endif
			
/* *********************************************** VELOCE ************************************************** */

	for(;;)
	{
		do {
			rdset=all;

#ifdef VICDEBUG
			stampa_fd_set("rdset prima",&rdset);
#endif

			ris=select(maxfd+1,&rdset,NULL,NULL,NULL);
		} while( (ris<0) && (errno==EINTR) );
		if(ris<0) {
			perror("select failed: ");
			exit(1);
		}

#ifdef VICDEBUG
		stampa_fd_set("rdset dopo",&rdset);
#endif

		/* Lettura dei pacchetti UDP provenienti dal Monitor */
		if(FD_ISSET(monitordatafd,&rdset))
		{
			lettura_pkt_monitor();
		}

		/* Lettura dei pacchetti TCP (CONF, ACK, NACK) provenienti dal Monitor */
		if( FD_ISSET(monitorfd,&rdset) )
		{
			char ch; int ris;
			uint32_t tmpnumporte;
			uint16_t tmpporte[MAXNUMCONNECTIONS];
			uint32_t idmsg;

			/* ris=recv(monitorfd,buf,65536,MSG_DONTWAIT); */
			ris=recv(monitorfd,&ch,1,0);
			if(ris!=1) { fprintf(stderr,"recv from monitor failed: "); exit(9); }

			if(ch=='C') 
			{
				ris=recv(monitorfd,(char*)&tmpnumporte,sizeof(uint32_t),0);
				if(ris!=sizeof(uint32_t)) { fprintf(stderr,"(C)recv_configurazione failed: "); exit(9); }

				for(i=0;i<tmpnumporte;i++)
				{
 					ris=recv(monitorfd,&(tmpporte[i]),sizeof(uint16_t),0);
					if(ris!=sizeof(uint16_t)) { fprintf(stderr,"(C%d)recv_configurazione failed: ",i); exit(9); }

				}
				
				config_new_porte(cfgPorte, tmpporte);

				setup_new_configurazione(&numporte,porte,&tmpnumporte,tmpporte);

				/* Creazione del pacchetto della configurazione delle porte */
				config_pkt_porte(cfgPKT, numporte);
				
				send_config(cfgPKT, monitordatafd, cfgPorte, numporte);
			} 
			else if( ch=='A' ) 
			{
				ris=recv(monitorfd,(char*)&idmsg,sizeof(uint32_t),0);
				if(ris!=sizeof(uint32_t)) { fprintf(stderr,"(A)recv ack failed: "); exit(9); }

				/* Se arriva un ACK presente nella lista di pacchetti, lo rimuove */
				if(find_id_pkt(idmsg, lPkt) != NULL)
				{
					lPkt = rim_pkt(idmsg, lPkt);
				}
				
				/* Incrementa il contatore degli ACK */
				contACK++;
			} 
			else if( ch=='N' ) 
			{
				struct listaPKT *list_aux;

				list_aux = NULL;

				ris=recv(monitorfd,(char*)&idmsg,sizeof(uint32_t),0);
				if(ris!=sizeof(uint32_t)) { fprintf(stderr,"(N)recv nack failed: "); exit(9); }

				/* Restituisce il puntatore lista all'elemento interessato */
				list_aux = find_id_pkt(idmsg, lPkt);

				/* Se il pacchetto NACKato è presente nella lista */
				if(list_aux != NULL)
				{
					/* Se precedentemente sono arrivati almeno due ACK dietro fila, vuol dire che attualmente il Mobile
					   è connesso sulla porta 'OK', quindi viene data una seconda chance al pacchetto rinviandolo sulla
					   medesima porta, altrimenti si scorre il vettore di porte dato che due NACK sulla stessa porta
					   indicano il cambiamento in 'LOSS' */

					if(contACK < NUM_CONTACK)
					{
						if(list_aux->portaPKT == cfgPorte[index])
						{
							index=(index+1)%numporte;
						}
					}
					else
					{
						contACK = 0;
					}

					/* Aggiorna anche la porta d'invio del pacchetto */
					list_aux->portaPKT = cfgPorte[index];
					
					/* Rispedisce l'esatto pacchetto che è stato NACKato */
					ris=send_udp(monitordatafd, (char*)list_aux->pkt, sizeof(list_aux->pkt) , 1000, "127.0.0.1", cfgPorte[index] );
					if(!(ris))
					{
						fprintf(stderr,"pkt id %u NOT sent\n", list_aux->pkt[0] );
					}
				}
			}

		}
		
		/* Controlla se sono arrivati pacchetti dall'applicazione */
		if( FD_ISSET(appmobilefd,&rdset) )
		{
			lettura_pkt_app();
		}


	} /* fine for ;; */
	
/***********************************************************************************************************/
			
			break;
		case CONN_LENTA:
						
#ifdef TIPO_CONN
			fprintf(stdout,ORANGE "\n*** Attivazione della connessione LENTA ***\n" DEFAULTCOLOR "\n");
#endif
			
/* *********************************************** LENTA ************************************************** */

	for(;;)
	{
		do {
			rdset=all;

#ifdef VICDEBUG
			stampa_fd_set("rdset prima",&rdset);
#endif

			ris=select(maxfd+1,&rdset,NULL,NULL,NULL);
		} while( (ris<0) && (errno==EINTR) );
		if(ris<0) {
			perror("select failed: ");
			exit(1);
		}

#ifdef VICDEBUG
		stampa_fd_set("rdset dopo",&rdset);
#endif

		/* Lettura dei pacchetti UDP provenienti dal Monitor */
		if(FD_ISSET(monitordatafd,&rdset))
		{
			lettura_pkt_monitor();
		}

		/* Lettura dei pacchetti TCP (CONF, ACK, NACK) provenienti dal Monitor */
		if( FD_ISSET(monitorfd,&rdset) )
		{
			char ch; int ris;
			uint32_t tmpnumporte;
			uint16_t tmpporte[MAXNUMCONNECTIONS];
			uint32_t idmsg;

			/* ris=recv(monitorfd,buf,65536,MSG_DONTWAIT); */
			ris=recv(monitorfd,&ch,1,0);
			if(ris!=1) { fprintf(stderr,"recv from monitor failed: "); exit(9); }

			if(ch=='C') 
			{	
				ris=recv(monitorfd,(char*)&tmpnumporte,sizeof(uint32_t),0);
				if(ris!=sizeof(uint32_t)) { fprintf(stderr,"(C)recv_configurazione failed: "); exit(9); }

				for(i=0;i<tmpnumporte;i++)
				{
 					ris=recv(monitorfd,&(tmpporte[i]),sizeof(uint16_t),0);
					if(ris!=sizeof(uint16_t)) { fprintf(stderr,"(C%d)recv_configurazione failed: ",i); exit(9); }

				}
				
				config_new_porte(cfgPorte, tmpporte);

				setup_new_configurazione(&numporte,porte,&tmpnumporte,tmpporte);

				/* Creazione del pacchetto della configurazione delle porte */
				config_pkt_porte(cfgPKT, numporte);
				
				send_config(cfgPKT, monitordatafd, cfgPorte, numporte);
			} 
			else if( ch=='A' ) 
			{
				ris=recv(monitorfd,(char*)&idmsg,sizeof(uint32_t),0);
				if(ris!=sizeof(uint32_t)) { fprintf(stderr,"(A)recv ack failed: "); exit(9); }

				/* Se arriva un ACK presente nella lista di pacchetti, lo rimuove */
				if(find_id_pkt(idmsg, lPkt) != NULL)
				{
					lPkt = rim_pkt(idmsg, lPkt);
				}
			} 
			else if( ch=='N' ) 
			{
				struct listaPKT *list_aux;

				list_aux = NULL;

				ris=recv(monitorfd,(char*)&idmsg,sizeof(uint32_t),0);
				if(ris!=sizeof(uint32_t)) { fprintf(stderr,"(N)recv nack failed: "); exit(9); }

				/* Restituisce il puntatore lista all'elemento interessato */
				list_aux = find_id_pkt(idmsg, lPkt);

				/* Se il pacchetto NACKato è presente nella lista */
				if(list_aux != NULL)
				{
					/* Se non sono arrivati dei NACK precedentemente, viene data la seconda chance all'attuale pacchetto
					   NACKato, altrimenti si scorre il vettore di porte */
					if(contACK > 0)
					{
						if(list_aux->portaPKT == cfgPorte[index])
						{
							index=(index+1)%numporte;
						}
						contACK = 0;
					}
					/* Aggiorna anche la porta d'invio del pacchetto */
					list_aux->portaPKT = cfgPorte[index];
					
					/* Rispedisce l'esatto pacchetto che è stato NACKato */
					ris=send_udp(monitordatafd, (char*)list_aux->pkt, sizeof(list_aux->pkt) , 1000, "127.0.0.1", cfgPorte[index] );
					if(!(ris))
					{
						fprintf(stderr,"pkt id %u NOT sent\n", list_aux->pkt[0] );
					}
					
					contACK++;
				}
			}

		}
		
		/* Controlla se sono arrivati pacchetti dall'applicazione */
		if( FD_ISSET(appmobilefd,&rdset) )
		{
			lettura_pkt_app();
		}


	} /* fine for ;; */
	
/***********************************************************************************************************/
			
			break;
		default:
			fprintf(stderr,"Errore durante la configurazione del tipo di connessione.\n");
			exit(1);
			break;
	}
	
	close(monitorfd);
	return(0);
}
Esempio n. 15
0
void function( char data)					//1 for extention , 0 for basic  * must off graphic before go back basic function
{
	send_config(0x30 |data << 2);
}
Esempio n. 16
0
void lcd_clr(void)						//clear the lcd
{	
 	send_config(0x01);
	delay(600);	
}
Esempio n. 17
0
int main(int argc, char **argv) {
    const char *mode = "CGRAY";
    int resolution = 100;
    if(argc > 1) {
        switch(*argv[1]) {
            case 'c': mode = "CGRAY";  break;
            case 'g': mode = "GRAY64"; break;
            case 't': mode = "TEXT";   break;
            case '-': mode = NULL;     break;
            default:
                fprintf(stderr, "ERROR: unrecognised mode, "
                                "should be one of [cgt]\n");
                return 1;
        }
    }
    if(argc > 2) {
        resolution = atoi(argv[2]);
        if(resolution < 100 || resolution > 600 || resolution % 100) {
            fprintf(stderr, "ERROR: resolution must be a positive "
                            "multiple of 100 no greater than 600\n");
            return 1;
        }
    }

    libusb_context *context;
    libusb_init(&context);
    device_handle = libusb_open_device_with_vid_pid(context, VID, PID);
    if(!device_handle) {
        fprintf(stderr, "ERROR: Unable to find device "
                        "(Vendor ID = %04x, Product ID = %04x)\n",
                VID, PID);
        return 1;
    }
    libusb_claim_interface(device_handle, 0);
    libusb_set_interface_alt_setting(device_handle, 0, 0);

    control_in_vendor_device(1, 2, 0, 255); /* returns 05 10 01 02 00 */
    if(mode) {
        char *config = build_config(
                mode, MIN(resolution, 300), resolution,
                PAGE_WIDTH * MIN(resolution, 300)/100,
                PAGE_HEIGHT * resolution/100);
        send_config(config); free(config);
    }
    int page = 1;
    FILE *fp = NULL;
    int sleep_time = 0;
    while(1) {
        unsigned char buf[0x1000];
        int num_bytes = bulk_read(4, buf, 0x1000);
        if(num_bytes) sleep_time = 0;
        if(num_bytes > 2) {
            if(!fp) {
                char fname[8];
                snprintf(fname, 8, "%03d.raw", page);
                fprintf(stderr, "Opening '%s'...\n", fname);
                fp = fopen(fname, "wb");
            }
            fwrite(buf, 1, num_bytes, fp);
        } else if(num_bytes == 0 && sleep_time < 10) {
#ifdef DEBUG
            fprintf(stderr, "Sleeping\n");
#endif
            sleep_time++;
            usleep(200 * 1000);
        } else if(num_bytes == 2 && buf[0] == 0xc2 && buf[1] == 0x00) {
            fprintf(stderr, "ERROR: Nothing to scan\n"); break;
        } else if(num_bytes == 2 && buf[0] == 0xc3 && buf[1] == 0x00) {
            fprintf(stderr, "ERROR: Paper jam\n"); break;
        } else if(num_bytes == 1 && buf[0] == 0x80) {
            fprintf(stderr, "No more pages\n"); break;
        } else if((num_bytes == 1 && buf[0] == 0x81) || sleep_time >= 10) {
            fprintf(stderr, "Feeding in another page");
            if(sleep_time >= 10) fprintf(stderr, " (timeout)");
            fprintf(stderr, "\n");
            fclose(fp); fp = NULL;
            send_config("");
            page++;
            sleep_time = 0;
        } else if(num_bytes == 1 && buf[0] == 0xc3) {
            fprintf(stderr, "Paper jam\n"); break;
        } else if(num_bytes == 1 && buf[0] == 0xc4) {
            fprintf(stderr, "Scan aborted\n"); break;
        } else {
            fprintf(stderr, "Received unknown data: %02x", buf[0]);
            if(num_bytes == 2) fprintf(stderr, " %02x", buf[1]);
            fprintf(stderr, "\n");
            break;
        }
    }
    if(fp) fclose(fp);
    control_in_vendor_device(2, 2, 0, 255); /* returns 05 10 02 02 00 */

    libusb_release_interface(device_handle, 0);
    libusb_close(device_handle);
    libusb_exit(context);
    return 0;
}
Esempio n. 18
0
//==================================================================================
//	main function					(main fucntion of the program)
//===================================================================================
void main(void)
{
	//assign variable
	unsigned char i=0,database;				
	unsigned char data[10];
	unsigned int m,j;

	init();
	d_graphic(0);					//display cytron logo
	delay(300000);					//delay for pic display

	// display claibrating messages
	send_config(0b00110000);			//set to function set configuration
	lcd_clr();					//clear the lcd
	send_string(cali);				//display string
	lcd_goto (8);					//cursor at 3rd character line
	send_string(mssg1);				//display string mssg1
	lcd_goto(24);					//cursor at 4th  character line
	send_string(mssg2);				//display string mssg2

	while(SW1);					//wait for button pushed
	while(!SW1);					//wait for button release
	calibrate();					//taking the current force as reference for flat plane
	lcd_clr();					//clear the lcd
	

	lcd_goto(1);					//cursor at 3rd character, 1st character line
	send_string(mssg3);				//display string mssg3
	lcd_goto(17);					//cursor at 3rd character, 2st character line
	send_string(mssg4);				//display string mssg4
	lcd_goto(0);					//cursor at 1st character, 1st character line
	send_char(0x10);				//display symbol arrow
	m =0 ;						//set the variable 0

	while(1)					//loop forever
	{

		if (!SW1)				//if sw1 is pressed, increase mode
		{
			while(!SW1);			//wait until sw1 is release
			m++;				//increament m
			if (m>1) m=0;			//if m more than 1 , clear m

			if (m==1) 			//if m is 1
			{
				lcd_goto(0);		//cursor at 1st line
				send_char('  ');	//space 1st and 2nd character , 1st line
				lcd_goto(16);		//cursor at 2nd line
				send_char(0x10);	//display arrow at 2nd charater, 2nd line
			}
			else 
			{
				lcd_goto(0);		//cursor at 1st line
				send_char(0x10);	//display arrow at 2nd charater, 1st line
				lcd_goto(16);		//cursor at 2nd line
				send_char('  ');	//space 1st and 2nd character , 2nd line
			}
		}

		else if (!SW2)					//if sw is pressed
		{
			while(!SW2);				//wait until sw2 is released
			lcd_clr();				//clear all character
			clr_graphic();				//clear all graphic

			// 16 bit timer initial status and start timer
			TMR0H = 194;						// value for timer reach overflow in 50 ms for clock 10MIPS		
			TMR0L = 246;
			T0CONbits.TMR0ON = 1;					//start timer

			while(1)						//loop forever
			{
				if (INTCONbits.TMR0IF==1)			//if timer over flow ( occur every 50 ms) // to update data every 50 ms
				{
					INTCONbits.TMR0IF==0;			//clear the flag bit
					TMR0H=194;				//value for timer reach overflow in 50 ms for clock 10MIPS		
					TMR0L=246;
					if (m==1) friction();			//if mode is 1 , the do calculation friction, else do calculation freespace.
					else 	freespace();			//update the data ( required for more accurate intergration ( faster, more accurate )) 

					i++;					//increment variable i
				}
					
				if (i==10) 					//if i reach ten ( around 500 ms) update the icon position
				{
					if((x_dis/sens >60)||(x_dis/sens<-60)||(y_dis/sens>28)||(y_dis/sens<-28))	//if the icon position not in range of glcd
					{																					//mean 'the ball drop out from glcd'
						d_graphic(1);			//display graphic 
						delay(300000);			//dealy for display the graphic
						d_graphic(2);			//display another graphic
						delay(300000);				
			 			while(1);
					}
					d_icon(60-(x_dis/sens),28+(y_dis/sens));		//display icon at updated x,y position
					i=0;							//clear the variable i
				}
			}
		}	
	}
}
Esempio n. 19
0
//	main function					(main fucntion of the program)
//==========================================================================
void main()
{
	char read_sms_command[] = "AT+CMGR=1";
	char delete_sms_command[] = "AT+CMGD=1";
	
	
	//set I/O input output
	TRISB = 0b00000011;					//configure PORTB I/O direction
	TRISD = 0b00000000;					//configure PORTD I/O direction
	TRISA = 0b00000111;					//configure PORTA I/O direction
	
	LED1=0;								// OFF LED1
	LED2=0;								// OFF LED2

	//Configure UART
	SPBRG=10;			//set baud rate as 115200 baud
	BRGH=1;				//baud rate high speed option
	TXEN=1;				//enable transmission
	TX9 =0;				//8-bit transmission
	RX9 =0;				//8-bit reception	
	CREN=1;				//enable reception
	SPEN=1;				//enable serial port

	//setup ADC
	ADCON1 = 0b00000110;				//set ADx pin digital I/O
	
	//configure lcd
	send_config(0b00000001);			//clear display at lcd
	send_config(0b00000010);			//lcd return to home 
	send_config(0b00000110);			//entry mode-cursor increase 1
	send_config(0b00001100);			//display on, cursor off and cursor blink off
	send_config(0b00111000);			//function set

	//display startup message	
	lcd_clr();							//clear lcd
	send_string("Cytron Tech.");		//display "Cytron Tech."
	lcd_goto(20);						//set the lcd cursor to location 20
	send_string("Smart Home");			//display "Smart Home"

	// Delay for a while.
	delay(100000);
	
	
	
	// Clear the LCD and display the new message.
	lcd_clr();
	send_string("Testing Com...");
	
	// Make sure we can communicate with the GSM modem.
	gsm_send_command("AT");
	
	// Read the response.
	gsm_read_line(&gsm_response);
	
	// We should receive "OK" from the GSM modem.
	// If we don't, display "Error".
	if (memcmp("OK", &gsm_response, 2) != 0)
	{
		lcd_clr();
		send_string("Error...");
		while(1);
	}	
	
	
	
	// Clear the LCD and display the new message.
	lcd_clr();
	send_string("Waiting for");
	lcd_goto(20);
	send_string("Call Ready");
	
	// Waiting for the GSM modem to search for the network.
	// We will receive a blank line before receiving "Call Ready".
	gsm_read_line(&gsm_response);
	gsm_read_line(&gsm_response);
	
	// We should receive "Call Ready" from the GSM modem.
	// If we don't, display "Error".
	if (memcmp("Call Ready", &gsm_response, 10) != 0)
	{
		lcd_clr();
		send_string("Error...");
		while(1);
	}	
	
	
	
	// Clear the LCD and display the new message.
	lcd_clr();
	send_string("Setting Text");
	lcd_goto(20);
	send_string("Mode...");
	
	// Set text mode for SMS.
	gsm_send_command("AT+CMGF=1");
	
	// Read the "OK".
	gsm_read_line(&gsm_response);
	
	
	
	// Clear the LCD and display the new message.
	lcd_clr();
	send_string("Ready");
	
	

	while(1)
	{
		// Check whether there is new data from the GSM modem.
		if (RCIF == 1)
		{
			// Check is there a new SMS?
			gsm_read_line(&gsm_response);
			if (memcmp("+CMTI: \"SM\",", &gsm_response, 12) == 0)
			{
				// Get the SMS index.
				// The command array is already initialized as "AT+CMGR=1" and "AT+CMGD=1",
				// we need to changed the index to the actual one.
				read_sms_command[8] = gsm_response[12];
				delete_sms_command[8] = gsm_response[12];
				
				// Clear the LCD and display the new message.
				lcd_clr();
				send_string("Reading SMS...");
				
				// Send command to read the SMS.
				gsm_send_command(&read_sms_command);
				
				// Read the response.
				// The first line is the SMS info which we don't need.
				// We only need the second line which is the message content.
				gsm_read_line(&gsm_response);
				gsm_read_line(&command);
				
				// Read the newline and "OK".
				gsm_read_line(&gsm_response);
				gsm_read_line(&gsm_response);
				
				
				
				// Switch on the light if we received "on".
				if (memcmp("on", &command, 2) == 0)
				{
					LED1 = 1;
					LED2 = 1;
				}	
				
				// Switch off the light if we received "off".
				else if (memcmp("off", &command, 3) == 0)
				{
					LED1 = 0;
					LED2 = 0;
				}	
				
				
				
				// Send command to delete the SMS.
				gsm_send_command(&delete_sms_command);
				
				// Read the "OK".
				gsm_read_line(&gsm_response);
				
				
				
				// Clear the LCD and display the new message.
				lcd_clr();
				send_string("Ready...");
			}
		}	
		
		
		
		// Check whether SW1 is pressed.
		if (SW1 == 0)
		{
			// Clear the LCD and display the new message.
			lcd_clr();
			send_string("Sending SMS...");
			
			// Send the SMS to notify the owner.
			// Please change this to your own number.
			gsm_send_command("AT+CMGS=\"0123456789\"");
			
			// We should receive '>' from the modem.
			// If we don't, display "Error".
			if (uart_rec() != '>')
			{
				lcd_clr();
				send_string("Error...");
				while(1);
			}	
			
			// Send the message.
			uart_str("Warning: Switch 1 has been triggered !");
			
			// Send <CTRL+Z>.
			uart_send(0x1a);
			
			
			
			// Read the newline and response.
			gsm_read_line(&gsm_response);
			gsm_read_line(&gsm_response);
			
			// We should receive "+CMGS: <Message ID>" from the GSM modem.
			// If we don't, display "Error".
			if (memcmp("+CMGS:", &gsm_response, 6) != 0)
			{
				lcd_clr();
				send_string("Error...");
				while(1);
			}
			
			
			
			// Read the newline and "OK".
			gsm_read_line(&gsm_response);
			gsm_read_line(&gsm_response);
			
			
			
			// Clear the LCD and display the new message.
			lcd_clr();
			send_string("Ready...");
			
			
			
			// Wait until SW1 is released so that we don't send duplicated message.
			while (SW1 == 0);
			
		}	
	}
}
//============================================================================================
//	main function
//============================================================================================
void main(void)
{
	ADCON1=0b00000110;	//set all portA pins as digital I/O
	TRISA=0b11001111;   //clear bit 4&5 portA as output and set the rest as input
	TRISB=0b00000000;   //set portB as output
	TRISD=0b00000000;   //set portD as output
	TRISC=0b11110000;   //set bit4-7 portC as input(connected to 4 row of keypad)
	TRISE=0b00000000; 	//set portE as output

	PORTC=0;
	PORTD=0;
	RELAY=0;
	BUZZER=0;
	LED_YELLOW=0;
	LED_RED=0;

	send_config(0b00001001);                //clear display at lcd
	send_config(0b00000010);                //Lcd Return to home
	send_config(0b00000110);                //entry mode-cursor increase 1
	send_config(0b00001100);                //diplay on, cursor off and cursor blink off
	send_config(0b00111000);                //function
	
	lcd_clr();                          //clear LCD
	delay(1000);                        //delay
	lcd_goto(0);                        //initial display
	send_string("PLEASE ENTER");        //Display "PLEASE ENTER" on lcd
	lcd_goto(20);                       //Display on 2nd line
	send_string("6-DIGIT PASSWORD");    //Display "6-DIGIT PASSWORD" on lcd

	
	while(1)
	{                   //keypad scanning algorithm
			clearrow1();		//Clear 1st output pin and set the others
			scancolumn1();	//scan column 1-4
			clearrow2();		//Clear 2nd output pin and set the others
			scancolumn2();	//scan column
			clearrow3();		//Clear 3rd output pin and set the others
			scancolumn3();	//scan column
			clearrow4();		//Clear 4th output pin and set the others
			scancolumn4();	//scan column
			
	if(password_count==6)	
	{
            password_count=0;
            if((keyin_char[0]==stalled_char[0])&&(keyin_char[1]==stalled_char[1])&&
                (keyin_char[2]==stalled_char[2])&&(keyin_char[3]==stalled_char[3])&&
		(keyin_char[4]==stalled_char[4])&&(keyin_char[5]==stalled_char[5]))	//compare the keyin value with stalled value to test whether password is correct
                    {
                        lcd_clr();				//clear lcd
			lcd_goto(0);
			send_string("SUCCESS!");		//display SUCCESS
			LED_YELLOW=1;               //yellow light on
			RELAY=1;                    //relay on
			beep_once();                //beep one time
			while(1);                   //infinity loop
				}
	else
	{
            lcd_clr();						//clear lcd
            lcd_goto(0);
            send_string("ERROR!");//display ERROR!
            LED_RED=1;						//red light on
            beep_twice();					//beep two time
            while(1);             //infinity loop
                        }
			}
	}
}
void lcd_clr(void)
{
 	send_config(0x01);
	delay(50);	
}
int
main (int argc, char *argv[])
{
	GDBusProxy *proxy;
	GVariantBuilder builder, ip4builder, ip6builder;
	GVariant *ip4config, *ip6config;
	char *tmp;
	GVariant *val;
	int i;
	GError *err = NULL;
	GPtrArray *dns4_list, *dns6_list;
	GPtrArray *nbns_list;
	GPtrArray *dns_domains;
	struct in_addr temp_addr;
	int tapdev = -1;
	char **iter;
	int shift = 0;
	gboolean is_restart;
	gboolean has_ip4_prefix = FALSE;
	gboolean has_ip4_address = FALSE;
	gboolean has_ip6_address = FALSE;
	gchar *bus_name = NM_DBUS_SERVICE_OPENVPN;

#if !GLIB_CHECK_VERSION (2, 35, 0)
	g_type_init ();
#endif

	for (i = 1; i < argc; i++) {
		if (!strcmp (argv[i], "--")) {
			i++;
			break;
		}
		if (nm_streq (argv[i], "--debug")) {
			if (i + 2 >= argc) {
				g_printerr ("Missing debug arguments (requires <LEVEL> <PREFIX_TOKEN>)\n");
				exit (1);
			}
			gl.log_level = _nm_utils_ascii_str_to_int64 (argv[++i], 10, 0, LOG_DEBUG, 0);
			gl.log_prefix_token = argv[++i];
		} else if (!strcmp (argv[i], "--tun"))
			tapdev = 0;
		else if (!strcmp (argv[i], "--tap"))
			tapdev = 1;
		else if (!strcmp (argv[i], "--bus-name")) {
			if (++i == argc) {
				g_printerr ("Missing bus name argument\n");
				exit (1);
			}
			if (!g_dbus_is_name (argv[i])) {
				g_printerr ("Invalid bus name\n");
				exit (1);
			}
			bus_name = argv[i];
		} else
			break;
	}
	shift = i - 1;

	if (_LOGD_enabled ()) {
		GString *args;

		args = g_string_new (NULL);
		for (i = 0; i < argc; i++) {
			if (i > 0)
				g_string_append_c (args, ' ');
			if (shift && 1 + shift == i)
				g_string_append (args, "  ");
			tmp = g_strescape (argv[i], NULL);
			g_string_append_printf (args, "\"%s\"", tmp);
			g_free (tmp);
		}

		_LOGD ("command line: %s", args->str);
		g_string_free (args, TRUE);

		for (iter = environ; iter && *iter; iter++)
			_LOGD ("environment: %s", *iter);
	}

	/* shift the arguments to the right leaving only those provided by openvpn */
	argv[shift] = argv[0];
	argv += shift;
	argc -= shift;

	is_restart = argc >= 7 && !g_strcmp0 (argv[6], "restart");

	proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
	                                       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
	                                       NULL,
	                                       bus_name,
	                                       NM_VPN_DBUS_PLUGIN_PATH,
	                                       NM_VPN_DBUS_PLUGIN_INTERFACE,
	                                       NULL, &err);
	if (!proxy) {
		_LOGW ("Could not create a D-Bus proxy: %s", err->message);
		g_error_free (err);
		exit (1);
	}

	g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
	g_variant_builder_init (&ip4builder, G_VARIANT_TYPE_VARDICT);
	g_variant_builder_init (&ip6builder, G_VARIANT_TYPE_VARDICT);

	/* External world-visible VPN gateway */
	val = trusted_remote_to_gvariant ();
	if (val)
		g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY, val);
	else
		helper_failed (proxy, "VPN Gateway");

	/* Internal VPN subnet gateway */
	tmp = getenv ("route_vpn_gateway");
	val = addr4_to_gvariant (tmp);
	if (val)
		g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_INT_GATEWAY, val);
	else {
		val = addr6_to_gvariant (tmp);
		if (val)
			g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_INT_GATEWAY, val);
	}

	/* VPN device */
	tmp = getenv ("dev");
	val = str_to_gvariant (tmp, FALSE);
	if (val)
		g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_CONFIG_TUNDEV, val);
	else
		helper_failed (proxy, "Tunnel Device");

	if (tapdev == -1)
		tapdev = strncmp (tmp, "tap", 3) == 0;

	/* IPv4 address */
	tmp = getenv ("ifconfig_local");
	if (!tmp && is_restart)
		tmp = argv[4];
	if (tmp && strlen (tmp)) {
		val = addr4_to_gvariant (tmp);
		if (val) {
			has_ip4_address = TRUE;
			g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS, val);
		} else
			helper_failed (proxy, "IP4 Address");
	}

	/* PTP address; for vpnc PTP address == internal IP4 address */
	tmp = getenv ("ifconfig_remote");
	if (!tmp && is_restart)
		tmp = argv[5];
	val = addr4_to_gvariant (tmp);
	if (val) {
		/* Sigh.  Openvpn added 'topology' stuff in 2.1 that changes the meaning
		 * of the ifconfig bits without actually telling you what they are
		 * supposed to mean; basically relying on specific 'ifconfig' behavior.
		 */
		if (tmp && !strncmp (tmp, "255.", 4)) {
			guint32 addr;

			/* probably a netmask, not a PTP address; topology == subnet */
			addr = g_variant_get_uint32 (val);
			g_variant_unref (val);
			val = g_variant_new_uint32 (nm_utils_ip4_netmask_to_prefix (addr));
			g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_PREFIX, val);
			has_ip4_prefix = TRUE;
		} else
			g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_PTP, val);
	}

	/* Netmask
	 *
	 * Either TAP or TUN modes can have an arbitrary netmask in newer versions
	 * of openvpn, while in older versions only TAP mode would.  So accept a
	 * netmask if passed, otherwise default to /32 for TUN devices since they
	 * are usually point-to-point.
	 */
	tmp = getenv ("ifconfig_netmask");
	if (tmp && inet_pton (AF_INET, tmp, &temp_addr) > 0) {
		val = g_variant_new_uint32 (nm_utils_ip4_netmask_to_prefix (temp_addr.s_addr));
		g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_PREFIX, val);
	} else if (!tapdev) {
		if (has_ip4_address && !has_ip4_prefix) {
			val = g_variant_new_uint32 (32);
			g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_PREFIX, val);
		}
	} else
		_LOGW ("No IP4 netmask/prefix (missing or invalid 'ifconfig_netmask')");

	val = get_ip4_routes ();
	if (val)
		g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_ROUTES, val);
	else if (is_restart) {
		g_variant_builder_add (&ip4builder, "{sv}",
		                       NM_VPN_PLUGIN_IP4_CONFIG_PRESERVE_ROUTES,
		                       g_variant_new_boolean (TRUE));
	}

	/* IPv6 address */
	tmp = getenv ("ifconfig_ipv6_local");
	if (tmp && strlen (tmp)) {
		val = addr6_to_gvariant (tmp);
		if (val) {
			g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_ADDRESS, val);
			has_ip6_address = TRUE;
		} else
			helper_failed (proxy, "IP6 Address");
	}

	/* IPv6 remote address */
	tmp = getenv ("ifconfig_ipv6_remote");
	if (tmp && strlen (tmp)) {
		val = addr6_to_gvariant (tmp);
		if (val)
			g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_PTP, val);
		else
			helper_failed (proxy, "IP6 PTP Address");
	}

	/* IPv6 netbits */
	tmp = getenv ("ifconfig_ipv6_netbits");
	if (tmp && strlen (tmp)) {
		long int netbits;

		errno = 0;
		netbits = strtol (tmp, NULL, 10);
		if (errno || netbits < 0 || netbits > 128) {
			_LOGW ("Ignoring invalid prefix '%s'", tmp);
		} else {
			val = g_variant_new_uint32 ((guint32) netbits);
			g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_PREFIX, val);
		}
	}

	val = get_ip6_routes ();
	if (val)
		g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_ROUTES, val);
	else if (is_restart) {
		g_variant_builder_add (&ip6builder, "{sv}",
		                       NM_VPN_PLUGIN_IP6_CONFIG_PRESERVE_ROUTES,
		                       g_variant_new_boolean (TRUE));
	}

	/* DNS and WINS servers */
	dns_domains = g_ptr_array_sized_new (3);
	dns4_list = g_ptr_array_new ();
	dns6_list = g_ptr_array_new ();
	nbns_list = g_ptr_array_new ();

	for (i = 1; i < 256; i++) {
		char *env_name;

		env_name = g_strdup_printf ("foreign_option_%d", i);
		tmp = getenv (env_name);
		g_free (env_name);

		if (!tmp || strlen (tmp) < 1)
			break;

		if (!g_str_has_prefix (tmp, "dhcp-option "))
			continue;

		tmp += 12; /* strlen ("dhcp-option ") */

		if (g_str_has_prefix (tmp, "DNS "))
			parse_addr_list (dns4_list, dns6_list, tmp + 4);
		else if (g_str_has_prefix (tmp, "WINS "))
			parse_addr_list (nbns_list, NULL, tmp + 5);
		else if (g_str_has_prefix (tmp, "DOMAIN ") && is_domain_valid (tmp + 7))
			g_ptr_array_add (dns_domains, tmp + 7);
	}

	if (dns4_list->len) {
		val = g_variant_new_array (G_VARIANT_TYPE_UINT32, (GVariant **) dns4_list->pdata, dns4_list->len);
		g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_DNS, val);
	}

	if (has_ip6_address && dns6_list->len) {
		val = g_variant_new_array (G_VARIANT_TYPE ("ay"), (GVariant **) dns6_list->pdata, dns6_list->len);
		g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_DNS, val);
	}

	if (nbns_list->len) {
		val = g_variant_new_array (G_VARIANT_TYPE_UINT32, (GVariant **) nbns_list->pdata, nbns_list->len);
		g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_NBNS, val);
	}

	if (dns_domains->len) {
		val = g_variant_new_strv ((const gchar **) dns_domains->pdata, dns_domains->len);
		g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_DOMAINS, val);

		/* Domains apply to both IPv4 and IPv6 configurations */
		if (has_ip6_address) {
			val = g_variant_new_strv ((const gchar **) dns_domains->pdata, dns_domains->len);
			g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_DOMAINS, val);
		}
	}

	g_ptr_array_unref (dns4_list);
	g_ptr_array_unref (dns6_list);
	g_ptr_array_unref (nbns_list);
	g_ptr_array_unref (dns_domains);

	/* Tunnel MTU */
	tmp = getenv ("tun_mtu");
	if (tmp && strlen (tmp)) {
		long int mtu;

		errno = 0;
		mtu = strtol (tmp, NULL, 10);
		if (errno || mtu < 0 || mtu > 20000) {
			_LOGW ("Ignoring invalid tunnel MTU '%s'", tmp);
		} else {
			val = g_variant_new_uint32 ((guint32) mtu);
			g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_CONFIG_MTU, val);
		}
	}

	ip4config = g_variant_builder_end (&ip4builder);

	if (g_variant_n_children (ip4config)) {
		val = g_variant_new_boolean (TRUE);
		g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_CONFIG_HAS_IP4, val);
	} else {
		g_variant_unref (ip4config);
		ip4config = NULL;
	}

	ip6config = g_variant_builder_end (&ip6builder);

	if (g_variant_n_children (ip6config)) {
		val = g_variant_new_boolean (TRUE);
		g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_CONFIG_HAS_IP6, val);
	} else {
		g_variant_unref (ip6config);
		ip6config = NULL;
	}

	if (!ip4config && !ip6config)
		helper_failed (proxy, "IPv4 or IPv6 configuration");

	/* Send the config info to nm-openvpn-service */
	send_config (proxy, g_variant_builder_end (&builder), ip4config, ip6config);

	g_object_unref (proxy);

	return 0;
}