static irqreturn_t ux_interrupt(int irq, void *dev_id) { struct net_device *dev = dev_id; struct ux_private *priv = netdev_priv(dev); struct sk_buff *skb = dev_alloc_skb(ETH_FRAME_LEN); int ret; if (!priv->ux_init_done) { enable_ux_self(); priv->ux_init_done = 1; } skb->dev = dev; if ((ret = lx_read(priv->fd, skb->data, ETH_FRAME_LEN)) < 0) { if (ret != -EAGAIN) printk("uxdev: Error reading packet data: %d\n", ret); /* else: ping interrupt, ignore */ dev_kfree_skb(skb); return IRQ_HANDLED; } skb_put(skb, ret); /* ACK interrupt */ lx_kill(priv->prov_pid, SIGUSR1); skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); return IRQ_HANDLED; }
lx_size_t lx_fread(void *ptr, lx_size_t size, lx_size_t nmemb, LX_FILE *f) { int r = lx_read(f->fd, ptr, size * nmemb); if (r < 0) return 0; return r / size; }
gint lx_read_full(gint fd, gpointer buf, gsize len) { gint octets_read = 0; guint8 *start = buf; while (octets_read < len) { gint noctets = lx_read(fd, start, len - octets_read); if (noctets < 0) { return -1; } else if (noctets == 0) { goto end; } else { octets_read += noctets; start += noctets; } } end: return octets_read; }
int main(int argc, char **argv) { lx_t lx; // the brickOS executable char *filename; int opt; #ifdef HAVE_GETOPT_LONG int option_index; #endif unsigned char buffer[256+3]=""; char *tty=NULL; while((opt=getopt_long(argc, argv, "r:p:d:s:t:i:n:ev", (struct option *)long_options, &option_index) )!=-1) { switch(opt) { case 'e': run_flag=1; break; case 'r': sscanf(optarg,"%d",&rcxaddr); if (rcxaddr > ADDR_MAX || rcxaddr < ADDR_MIN) { fprintf(stderr, "LNP host address not in range 0..15\n"); return -1; } rcxaddr = (rcxaddr << 4) & CONF_LNP_HOSTMASK; break; case 'p': sscanf(optarg,"%d",&prog); break; case 's': sscanf(optarg,"%d",&srcport); if (srcport > ADDR_MAX || srcport < ADDR_MIN) { fprintf(stderr, "LNP port number not in range 0..15\n"); return -1; } break; case 't': sscanf(optarg,"%s",buffer); break; case 'i': sscanf(optarg,"%x",&irmode); break; case 'd': sscanf(optarg,"%d",&prog); pdelete_flag=1; break; case 'n': sscanf(optarg,"%d",&hostaddr); if (hostaddr > ADDR_MAX || hostaddr < ADDR_MIN) { fprintf(stderr, "LNP host address not in range 0..15\n"); return -1; } hostaddr_flag=1; break; case 'v': verbose_flag=1; break; } } if (prog > PROG_MAX || prog < PROG_MIN) { fprintf(stderr, "Program not in range 1..8\n"); return -1; } // load executable // if(((argc-optind < 1) && !(pdelete_flag || hostaddr_flag)) || ((argc-optind > 0 ) && (pdelete_flag || hostaddr_flag))) { char *usage_string = "Options:\n" " -p<prognum> , --program=<prognum> set destination program to <prognum>\n" " -r<rcxaddr> , --rcxaddr=<rcxaddr> send to RCX host address <rcxaddr>\n" " -s<srcport> , --srcport=<srcport> send to RCX source port <srcport>\n" " -t<comport> , --tty=<comport> set IR Tower com port <comport>\n" #if defined(_WIN32) " -t<usb> , --tty=<usb> set IR Tower USB mode \n" #else " (if \"usb\" is in the port, use USB mode)\n" #endif " -i<0/1> , --irmode=<0/1> set IR mode near(0)/far(1) on RCX\n" " -e , --execute execute program after download\n" " -v , --verbose verbose mode\n" "\nCommands:\n" " -d<prognum> , --delete=<prognum> delete program <prognum> from memory\n" " -n<hostaddr> , --node=<hostaddr> set LNP host address in brick\n" "\n" "Default COM port or USB support can be set using environment variable RCXTTY.\n" "Eg:\tset RCXTTY=COM2\n" "\tset RCXTTY=USB\n" "\n" ; fprintf(stderr, "usage: %s [options] [command | file.lx]\n", argv[0]); fprintf(stderr, usage_string); return -1; } // Ignore filename if -dn or -na given if (!(pdelete_flag || hostaddr_flag)) { filename=argv[optind++]; if(lx_read(&lx,filename)) { fprintf(stderr,"unable to load brickOS executable from %s.\n",filename); return -1; } } // Moved tty device setting for a new option on command line if (buffer[0]) tty=buffer; if (!tty) tty = getenv(TTY_VARIABLE); if (!tty) tty = DEFAULTTTY; // Check if USB IR tower is selected. #if defined(_WIN32) if (stricmp(tty, "usb")==0) { tty_usb = 1; if(verbose_flag) fputs("\n\n Hary Mahesan - LEGO USB IR Tower Mode\n\n",stderr); tty="\\\\.\\legotower1"; // Set the correct usb tower if you have more than one (unlikely). } #elif defined(LINUX) || defined(linux) /* If the tty string contains "usb", e.g. /dev/usb/lego0, we */ /* assume it is the USB tower. /dev/usb/lego0 is the default name of */ /* the device in the LegoUSB (http://legousb.sourceforge.net) project. */ /* If yours doesn't contain the "usb" string, just link it. */ if (strstr(tty,"usb") !=0) { tty_usb=1; if (verbose_flag) fputs("\nC.P. Chan & Tyler Akins - USB IR Tower Mode for Linux.\n",stderr); } #endif LNPinit(tty); if (verbose_flag) fputs("\nLNP Initialized...\n",stderr); lnp_addressing_set_handler(0,ahandler); if(verbose_flag) fprintf(stderr,"loader hostaddr=0x%02x hostmask=0x%02x portmask=0x%02x\n", rcxaddr & 0x00ff, LNP_HOSTMASK & 0x00ff, srcport & 0x00ff); // Set IR mode if (irmode != -1) { buffer[0]=CMDirmode; buffer[1]=irmode; if(lnp_assured_write(buffer,2,rcxaddr,srcport)) { fputs("error setting IR mode to far\n",stderr); return -1; } } // Set LNP host address if (hostaddr_flag) { if(verbose_flag) fputs("\nset LNP host address", stderr); buffer[0] = CMDsethost; buffer[1] = hostaddr; if(lnp_assured_write(buffer,2,rcxaddr,srcport)) { fputs("error setting host address\n",stderr); return -1; } fprintf(stderr, "LNP host address set to %d\n", hostaddr); return 0; } if(verbose_flag) fputs("\ndelete",stderr); buffer[0]=CMDdelete; buffer[1]=prog-1; // prog 0 if(lnp_assured_write(buffer,2,rcxaddr,srcport)) { fputs("error deleting program\n",stderr); return -1; } // All done if -dn given if (pdelete_flag) { fprintf(stderr, "P%d deleted\n", prog); return 0; } if(verbose_flag) fputs("\ncreate ",stderr); buffer[ 0]=CMDcreate; buffer[ 1]=prog-1; // prog 0 buffer[ 2]=lx.text_size>>8; buffer[ 3]=lx.text_size & 0xff; buffer[ 4]=lx.data_size>>8; buffer[ 5]=lx.data_size & 0xff; buffer[ 6]=lx.bss_size>>8; buffer[ 7]=lx.bss_size & 0xff; buffer[ 8]=lx.stack_size>>8; buffer[ 9]=lx.stack_size & 0xff; buffer[10]=lx.offset >> 8; // start offset from text segment buffer[11]=lx.offset & 0xff; buffer[12]=DEFAULT_PRIORITY; if(lnp_assured_write(buffer,13,rcxaddr,srcport)) { fputs("error creating program\n",stderr); return -1; } // relocation target address in relocate_to // lx_relocate(&lx,relocate_to); lnp_download(&lx); fprintf(stderr, "\n"); if (run_flag) { if(verbose_flag) fputs("\nrun ",stderr); buffer[0]=CMDrun; buffer[1]=prog-1; // prog 0 if(lnp_assured_write(buffer,2,rcxaddr,srcport)) { fputs("error running program\n",stderr); return -1; } } return 0; }
int main(int argc, char **argv) { lx_t lx; // the brickOS executable char *filename; int opt,option_index; unsigned char buffer[256+3]; while((opt=getopt_long(argc, argv, "r:p:s:v", long_options, &option_index) )!=-1) { switch(opt) { case 'r': sscanf(optarg,"%x",&rcxaddr); break; case 'p': sscanf(optarg,"%x",&prog); break; case 's': sscanf(optarg,"%x",&srcport); break; case 'v': verbose_flag=1; break; } } // validate parms if(prog < 1 || prog > 8) { fprintf(stderr,"Error: -p%d Invalid. BrickOS Supports [1-8].\n",prog); return -1; } else { prog--; } // load executable // if(argc-optind<1) { fprintf(stderr,"usage: %s file.lx\n" "[-rrcxaddress -pprogramnumber -ssrcport -v]\n", argv[0]); return -1; } filename=argv[optind++]; if(lx_read(&lx,filename)) { fprintf(stderr,"unable to load brickOS executable from %s.\n",filename); return -1; } if (lnp_init(0,0,0,0,0)) { fprintf(stderr,"unable to connect Tower\n"); return -1; } lnp_addressing_set_handler(0,ahandler); if(verbose_flag) fputs("\ndelete ",stderr); buffer[0]=CMDdelete; buffer[1]=prog; // prog 0 if(lnp_assured_write(buffer,2,rcxaddr,srcport)) { fputs("error deleting program\n",stderr); return -1; } if(verbose_flag) fputs("\ncreate ",stderr); buffer[ 0]=CMDcreate; buffer[ 1]=prog; // prog 0 buffer[ 2]=lx.text_size>>8; buffer[ 3]=lx.text_size & 0xff; buffer[ 4]=lx.data_size>>8; buffer[ 5]=lx.data_size & 0xff; buffer[ 6]=lx.bss_size>>8; buffer[ 7]=lx.bss_size & 0xff; buffer[ 8]=lx.stack_size>>8; buffer[ 9]=lx.stack_size & 0xff; buffer[10]=lx.offset >> 8; // start offset from text segment buffer[11]=lx.offset & 0xff; buffer[12]=DEFAULT_PRIORITY; if(lnp_assured_write(buffer,13,rcxaddr,srcport)) { fputs("error creating program\n",stderr); return -1; } // relocation target address in relocate_to // lx_relocate(&lx,relocate_to); lnp_download(&lx); #if 0 if(verbose_flag) fputs("\nrun ",stderr); buffer[0]=CMDrun; buffer[1]=prog; // prog 0 if(lnp_assured_write(buffer,2,rcxaddr,srcport)) { fputs("error running program\n",stderr); return -1; } #endif return 0; }