/*---------------------------------------------------------------------*/ PROCESS_THREAD(codeprop_process, ev, data) { PROCESS_BEGIN(); elfloader_init(); s.id = 0/*random_rand()*/; send_time = CLOCK_SECOND/4; PT_INIT(&s.udpthread_pt); PT_INIT(&s.recv_udpthread_pt); tcp_listen(HTONS(CODEPROP_DATA_PORT)); udp_conn = udp_broadcast_new(HTONS(CODEPROP_DATA_PORT), NULL); s.state = STATE_NONE; s.received = 0; s.addr = 0; s.len = 0; fd = cfs_open("codeprop-image", CFS_READ | CFS_WRITE); while(1) { PROCESS_YIELD(); if(ev == tcpip_event) { uipcall(data); } else if(ev == PROCESS_EVENT_TIMER) { tcpip_poll_udp(udp_conn); } } PROCESS_END(); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(console_server, ev, data) { static uint8_t buf[257]; static uint8_t processingFile = 0; static uint32_t received = 0; static struct cfs_dirent dirent; static struct cfs_dir dir; static uint32_t fdFile; static char *filename; PROCESS_BEGIN(); elfloader_init(); printf("Console server started !\n"); while(1) { PROCESS_YIELD(); if (ev == serial_line_event_message) { if (!strcmp(data, "ls")) { if(cfs_opendir(&dir, ".") == 0) { while(cfs_readdir(&dir, &dirent) != -1) { printf("File: %s (%ld bytes)\n", dirent.name, (long)dirent.size); } cfs_closedir(&dir); } } else if (!strcmp(data, "format")) { /* format the flash */ printf("Formatting\n"); printf("It takes around 3 minutes\n"); printf("...\n"); fdFile = cfs_coffee_format(); printf("Formatted with result %ld\n", fdFile); } else if (strstr(data, "cat") == data) { int n, jj; char* tmp = strstr(data, " "); tmp++; fdFile = cfs_open(tmp, CFS_READ); if (fdFile < 0) printf("error opening the file %s\n", tmp); while ((n = cfs_read(fdFile, buf, 60)) > 0) { for (jj = 0 ; jj < n ; jj++) printf("%c", (char)buf[jj]); } printf("\n"); cfs_close(fdFile); if (n!=0) printf("Some error reading the file\n"); } else if (strstr(data, "loadelf") == data) { filename = strstr(data, " "); filename++; // Cleanup previous loads if (elfloader_autostart_processes != NULL) autostart_exit(elfloader_autostart_processes); elfloader_autostart_processes = NULL; // Load elf file fdFile = cfs_open(filename, CFS_READ | CFS_WRITE); received = elfloader_load(fdFile); cfs_close(fdFile); printf("Result of loading %lu\n", received); // As the file has been modified and can't be reloaded, remove it printf("Remove dirty firmware '%s'\n", filename); cfs_remove(filename); // execute the program if (ELFLOADER_OK == received) { if (elfloader_autostart_processes) { PRINT_PROCESSES(elfloader_autostart_processes); autostart_start(elfloader_autostart_processes); } } else if (ELFLOADER_SYMBOL_NOT_FOUND == received) { printf("Symbol not found: '%s'\n", elfloader_unknown); } } else if (strstr(data, "rm") == data) { int n, jj; char* tmp = strstr(data, " "); tmp++; cfs_remove(tmp); } else if (strstr(data, "upload") == data) { char* tmp = strstr(data, " "); tmp++; fdFile = cfs_open(tmp, CFS_READ | CFS_WRITE); printf("Uploading file %s\n", tmp); processingFile = 1; } else if (!strcmp(data, "endupload")) { cfs_close(fdFile); printf("File uploaded (%ld bytes)\n", received); received = 0; processingFile = 0; } else if (processingFile) { int n = strlen(data); int r = decode(data, n, buf); received += r; cfs_write(fdFile, buf, r); } else { printf("%s (%lu bytes received)\n", (char*)data, received); } } } PROCESS_END(); }
PROCESS_THREAD(tftpd_process, ev, data) { static struct etimer t; static tftp_header *h; static int len, block, ack; static int tries; static int fd = -1; #if WITH_EXEC static char *elf_err; #endif PROCESS_BEGIN(); etimer_set(&t, CLOCK_CONF_SECOND*3); PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); setup_server(); #if WITH_EXEC elfloader_init(); #endif print_local_addresses(); while(1) { /* connection from client */ RECV_PACKET(h); len = 0; init_config(); if(h->op == uip_htons(TFTP_RRQ)) { connect_back(); PRINTF("< rrq for %s\n", h->filename); len += strlen(h->filename)+1; if(strcmp("octet", h->filename+len)) { send_error(EUNDEF, "only octet mode supported"); goto close_connection; } len += strlen(h->filename+len)+1; /* skip mode */ parse_opts(h->options+len, uip_datalen()-len-2); if(config.to_ack & OACK_ERROR) { send_error(EOPTNEG, ""); goto close_connection; } fd = cfs_open(h->filename, CFS_READ); if(fd<0) { send_error(ENOTFOUND, ""); goto close_connection; } block = 0; ack = 0; tries = TFTP_MAXTRIES; PRINTF("starting transfer...\n"); for(;;) { if(send_oack()) len = config.blksize; /* XXX hack to prevent loop exit*/ else len = send_data(fd, block+1); if(len<0) { send_error(EUNDEF, "read failed"); goto close_file; } RECV_PACKET_TIMEOUT(h,t); if(ev == PROCESS_EVENT_TIMER) { PRINTF("ack timed out, tries left: %d\n", tries); if(--tries<=0) goto close_file; continue; } if(h->op != uip_htons(TFTP_ACK)) { send_error(EBADOP, ""); goto close_file; } config.to_ack = 0; tries = TFTP_MAXTRIES; ack = uip_htons(h->block_nr); if(ack == block+1) block++; if(len < config.blksize && ack == block) goto done; } } else if(h->op == uip_htons(TFTP_WRQ)) { connect_back(); PRINTF("< wrq for %s\n", h->filename); len += strlen(h->filename)+1; strncpy(config.filename, h->filename, sizeof(config.filename)-1); if(strcmp("octet", h->filename+strlen(h->filename)+1)) { send_error(EUNDEF, "only octet mode supported"); goto close_connection; } len += strlen(h->filename+len)+1; /* skip mode */ parse_opts(h->options+len, uip_datalen()-len-2); if(config.to_ack & OACK_ERROR) { send_error(EOPTNEG, ""); goto close_connection; } cfs_remove(h->filename); fd = cfs_open(h->filename, CFS_WRITE); if(fd<0) { send_error(EACCESS, ""); goto close_connection; } block = 0; ack = 0; tries = TFTP_MAXTRIES; PRINTF("starting transfer...\n"); if(!send_oack()) send_ack(block); for(;;) { RECV_PACKET_TIMEOUT(h,t); if(ev == PROCESS_EVENT_TIMER) { PRINTF("data timed out, tries left: %d\n", tries); if(--tries<=0) goto close_file; len = config.blksize; /* XXX hack to prevent loop exit*/ goto resend_ack; } if(h->op != uip_htons(TFTP_DATA)) { send_error(EBADOP, ""); goto close_file; } config.to_ack = 0; tries = TFTP_MAXTRIES; ack = uip_htons(h->block_nr); if(ack != block+1) continue; /* else */ block++; len = recv_data(fd, block); if(len<0) { send_error(EUNDEF, "write failed"); goto close_file; } #if WITH_EXEC if(len < config.blksize) { if(config.exec) { if(exec_file(config.filename, &elf_err) != 0) { send_error(EUNDEF, elf_err); goto close_file; } } } #endif resend_ack: if(!send_oack()) send_ack(block); if(len < config.blksize) goto done; } } done: PRINTF("done.\n"); close_file: if(fd>=0) cfs_close(fd); fd = -1; close_connection: if(client_conn) uip_udp_remove(client_conn); client_conn = 0; PRINTF("connection closed.\n"); } PROCESS_END(); }