// this function implements the main loop of pict-o-crypt. void main_run(void) { // go to sleep SLEEP_DELAY seconds after progress stops sleep_delay(SLEEP_DELAY); for (;;) { led_unknown(); // if our usb device is attached... if (scsi_attached) { if (! walkfs(0) || ! walkfs(1)) { DFS_HostFlush(0); led_sad(code_usb); printf("walkfs failed\n"); } else { led_happy(); } do_scsi_wait(); } // if some other usb device is attached... if (other_attached) { do_other_wait(); } // if our usb host is attached... if (ftdi_attached) { main_run_admin(); } terminal_poll(); } }
void led_unknown_progress(void) { led_count[led_blue]++; #if PICTOCRYPT // go to sleep SLEEP_DELAY seconds after progress stops sleep_delay(SLEEP_DELAY); #endif }
static int __init zoltrix_init(void) { if (io == -1) { printk(KERN_ERR "You must set an I/O address with io=0x???\n"); return -EINVAL; } if ((io != 0x20c) && (io != 0x30c)) { printk(KERN_ERR "zoltrix: invalid port, try 0x20c or 0x30c\n"); return -ENXIO; } zoltrix_radio.priv = &zoltrix_unit; if (!request_region(io, 2, "zoltrix")) { printk(KERN_ERR "zoltrix: port 0x%x already in use\n", io); return -EBUSY; } if (video_register_device(&zoltrix_radio, VFL_TYPE_RADIO, radio_nr) == -1) { release_region(io, 2); return -EINVAL; } printk(KERN_INFO "Zoltrix Radio Plus card driver.\n"); init_MUTEX(&zoltrix_unit.lock); /* mute card - prevents noisy bootups */ /* this ensures that the volume is all the way down */ outb(0, io); outb(0, io); sleep_delay(); sleep_delay(); inb(io + 3); zoltrix_unit.curvol = 0; zoltrix_unit.stereo = 1; return 0; }
static void send_0_byte(int port, struct rt_device *dev) { if ((dev->curvol == 0) || (dev->muted)) { outb_p(128+64+16+ 1, port); /* wr-enable + data low */ outb_p(128+64+16+2+1, port); /* clock */ } else { outb_p(128+64+16+8+ 1, port); /* on + wr-enable + data low */ outb_p(128+64+16+8+2+1, port); /* clock */ } sleep_delay(1000); }
static int __init rtrack_init(void) { struct rtrack *rt = &rtrack_card; struct v4l2_device *v4l2_dev = &rt->v4l2_dev; int res; strlcpy(v4l2_dev->name, "rtrack", sizeof(v4l2_dev->name)); rt->io = io; if (rt->io == -1) { v4l2_err(v4l2_dev, "you must set an I/O address with io=0x20f or 0x30f\n"); return -EINVAL; } if (!request_region(rt->io, 2, "rtrack")) { v4l2_err(v4l2_dev, "port 0x%x already in use\n", rt->io); return -EBUSY; } res = v4l2_device_register(NULL, v4l2_dev); if (res < 0) { release_region(rt->io, 2); v4l2_err(v4l2_dev, "could not register v4l2_device\n"); return res; } strlcpy(rt->vdev.name, v4l2_dev->name, sizeof(rt->vdev.name)); rt->vdev.v4l2_dev = v4l2_dev; rt->vdev.fops = &rtrack_fops; rt->vdev.ioctl_ops = &rtrack_ioctl_ops; rt->vdev.release = video_device_release_empty; video_set_drvdata(&rt->vdev, rt); if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { v4l2_device_unregister(&rt->v4l2_dev); release_region(rt->io, 2); return -EINVAL; } v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n"); mutex_init(&rt->lock); outb(0x48, rt->io); sleep_delay(2000000); outb(0xc0, rt->io); return 0; }
static void send_0_byte(struct rtrack *rt) { if (rt->curvol == 0 || rt->muted) { outb_p(128+64+16+ 1, rt->io); /* wr-enable + data low */ outb_p(128+64+16+2+1, rt->io); /* clock */ } else { outb_p(128+64+16+8+ 1, rt->io); /* on + wr-enable + data low */ outb_p(128+64+16+8+2+1, rt->io); /* clock */ } sleep_delay(1000); }
static int __init rtrack_init(void) { struct rtrack *rt = &rtrack_card; struct v4l2_device *v4l2_dev = &rt->v4l2_dev; int res; strlcpy(v4l2_dev->name, "rtrack", sizeof(v4l2_dev->name)); rt->io = io; if (rt->io == -1) { v4l2_err(v4l2_dev, "you must set an I/O address with io=0x20f or 0x30f\n"); return -EINVAL; } if (!request_region(rt->io, 2, "rtrack")) { v4l2_err(v4l2_dev, "port 0x%x already in use\n", rt->io); return -EBUSY; } res = v4l2_device_register(NULL, v4l2_dev); if (res < 0) { release_region(rt->io, 2); v4l2_err(v4l2_dev, "could not register v4l2_device\n"); return res; } strlcpy(rt->vdev.name, v4l2_dev->name, sizeof(rt->vdev.name)); rt->vdev.v4l2_dev = v4l2_dev; rt->vdev.fops = &rtrack_fops; rt->vdev.ioctl_ops = &rtrack_ioctl_ops; rt->vdev.release = video_device_release_empty; video_set_drvdata(&rt->vdev, rt); if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { v4l2_device_unregister(&rt->v4l2_dev); release_region(rt->io, 2); return -EINVAL; } v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n"); /* Set up the I/O locking */ mutex_init(&rt->lock); /* mute card - prevents noisy bootups */ /* this ensures that the volume is all the way down */ outb(0x48, rt->io); /* volume down but still "on" */ sleep_delay(2000000); /* make sure it's totally down */ outb(0xc0, rt->io); /* steady volume, mute card */ return 0; }
static int zol_is_stereo (struct zol_device *dev) { int x1, x2; down(&dev->lock); outb(0x00, io); outb(dev->curvol, io); sleep_delay(); sleep_delay(); x1 = inb(io); sleep_delay(); x2 = inb(io); up(&dev->lock); if ((x1 == x2) && (x1 == 0xcf)) return 1; return 0; }
static void send_0_byte(struct rtrack *rt) { if (rt->curvol == 0 || rt->muted) { outb_p(128+64+16+ 1, rt->io); outb_p(128+64+16+2+1, rt->io); } else { outb_p(128+64+16+8+ 1, rt->io); outb_p(128+64+16+8+2+1, rt->io); } sleep_delay(1000); }
static int zol_getsigstr(struct zol_device *dev) { int a, b; down(&dev->lock); outb(0x00, io); /* This stuff I found to do nothing */ outb(dev->curvol, io); sleep_delay(); sleep_delay(); a = inb(io); sleep_delay(); b = inb(io); up(&dev->lock); if (a != b) return (0); if ((a == 0xcf) || (a == 0xdf) /* I found this out by playing */ || (a == 0xef)) /* with a binary scanner on the card io */ return (1); return (0); }
// this function displays a diagnostic code on a LED. void led_hex(int hex) { int i; int j; int n; int inv; if (debugger_attached) { asm_halt(); } else { splx(7); n = 0; inv = 0; for (;;) { if (n++ >= 10) { #if PICTOCRYPT sleep_delay(0); sleep_poll(); #endif } for (i = 0x10000000; i > 0; i /= 16) { if (hex < i) { continue; } j = (hex/i)%16; if (! j) { j = 16; } while (j--) { led_set(led_red, 1^inv); delay(200); led_set(led_red, 0^inv); delay(200); } delay(1000); } delay(3000); inv = ! inv; led_set(led_red, 0^inv); delay(3000); } } }
static int zol_setvol(struct zol_device *dev, int vol) { dev->curvol = vol; if (dev->muted) return 0; down(&dev->lock); if (vol == 0) { outb(0, io); outb(0, io); inb(io + 3); /* Zoltrix needs to be read to confirm */ up(&dev->lock); return 0; } outb(dev->curvol-1, io); sleep_delay(); inb(io + 2); up(&dev->lock); return 0; }
static int __init rtrack_init(void) { if(io==-1) { printk(KERN_ERR "You must set an I/O address with io=0x???\n"); return -EINVAL; } if (!request_region(io, 2, "rtrack")) { printk(KERN_ERR "rtrack: port 0x%x already in use\n", io); return -EBUSY; } rtrack_radio.priv=&rtrack_unit; if(video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr)==-1) { release_region(io, 2); return -EINVAL; } printk(KERN_INFO "AIMSlab RadioTrack/RadioReveal card driver.\n"); /* Set up the I/O locking */ mutex_init(&lock); /* mute card - prevents noisy bootups */ /* this ensures that the volume is all the way down */ outb(0x48, io); /* volume down but still "on" */ sleep_delay(2000000); /* make sure it's totally down */ outb(0xc0, io); /* steady volume, mute card */ rtrack_unit.curvol = 0; return 0; }
static int rt_setvol(struct rt_device *dev, int vol) { int i; down(&lock); if(vol == dev->curvol) { /* requested volume = current */ if (dev->muted) { /* user is unmuting the card */ dev->muted = 0; outb (0xd8, io); /* enable card */ } up(&lock); return 0; } if(vol == 0) { /* volume = 0 means mute the card */ outb(0x48, io); /* volume down but still "on" */ sleep_delay(2000000); /* make sure it's totally down */ outb(0xd0, io); /* volume steady, off */ dev->curvol = 0; /* track the volume state! */ up(&lock); return 0; } dev->muted = 0; if(vol > dev->curvol) for(i = dev->curvol; i < vol; i++) rt_incvol(); else for(i = dev->curvol; i > vol; i--) rt_decvol(); dev->curvol = vol; up(&lock); return 0; }
static int rt_setvol(struct rtrack *rt, int vol) { int i; mutex_lock(&rt->lock); if (vol == rt->curvol) { /* requested volume = current */ if (rt->muted) { /* user is unmuting the card */ rt->muted = 0; outb(0xd8, rt->io); /* enable card */ } mutex_unlock(&rt->lock); return 0; } if (vol == 0) { /* volume = 0 means mute the card */ outb(0x48, rt->io); /* volume down but still "on" */ sleep_delay(2000000); /* make sure it's totally down */ outb(0xd0, rt->io); /* volume steady, off */ rt->curvol = 0; /* track the volume state! */ mutex_unlock(&rt->lock); return 0; } rt->muted = 0; if (vol > rt->curvol) for (i = rt->curvol; i < vol; i++) rt_incvol(rt); else for (i = rt->curvol; i > vol; i--) rt_decvol(rt); rt->curvol = vol; mutex_unlock(&rt->lock); return 0; }
static int rt_setvol(struct rtrack *rt, int vol) { int i; mutex_lock(&rt->lock); if (vol == rt->curvol) { if (rt->muted) { rt->muted = 0; outb(0xd8, rt->io); } mutex_unlock(&rt->lock); return 0; } if (vol == 0) { outb(0x48, rt->io); sleep_delay(2000000); outb(0xd0, rt->io); rt->curvol = 0; mutex_unlock(&rt->lock); return 0; } rt->muted = 0; if (vol > rt->curvol) for (i = rt->curvol; i < vol; i++) rt_incvol(rt); else for (i = rt->curvol; i > vol; i--) rt_decvol(rt); rt->curvol = vol; mutex_unlock(&rt->lock); return 0; }
static void rt_decvol(void) { outb(0x58, io); /* volume down + sigstr + on */ sleep_delay(100000); outb(0xd8, io); /* volume steady + sigstr + on */ }
int main(int argc, char const *argv[]) { #ifdef _MEM_PROFILER uint8_t checkpoint_set = 0; #endif fd_set rfds; char buffer[PIPE_BUFFER_SIZE]; int i, n; Plugin plugins[MAX_PLUGINS]; int plugins_count = 0; mrb_state *mrb; mrb_value r_output, r_plugins_list; mrb_sym output_gv_sym, plugins_to_load_gv_sym; printf("Version: %s\n", PROBE_VERSION); if( argc != 2 ){ printf("Usage: %s <config_path>\n", argv[0]); exit(1); } #ifdef _MEM_PROFILER init_profiler(); #endif config_path = argv[1]; printf("Initializing core...\n"); mrb = mrb_open_allocf(profiler_allocf, "main"); output_gv_sym = mrb_intern_cstr(mrb, "$output"); plugins_to_load_gv_sym = mrb_intern_cstr(mrb, "$plugins_to_load"); setup_api(mrb); execute_file(mrb, "plugins/main.rb"); execute_file(mrb, config_path); printf("Loading plugins...\n"); r_plugins_list = mrb_gv_get(mrb, plugins_to_load_gv_sym); for(i = 0; i< mrb_ary_len(mrb, r_plugins_list); i++){ char *path, tmp[100]; int ssize; mrb_value r_plugin_name = mrb_ary_ref(mrb, r_plugins_list, i); const char *plugin_name = mrb_string_value_cstr(mrb, &r_plugin_name); snprintf(tmp, sizeof(tmp) - 1, "plugins/%s.rb", plugin_name); ssize = strlen(tmp); path = malloc(ssize + 1); strncpy(path, tmp, ssize); path[ssize] = '\0'; if( access(path, F_OK) == -1 ){ printf("cannot open plugin file \"%s\": %s\n", path, strerror(errno)); exit(1); } init_plugin_from_file(&plugins[plugins_count], path, plugin_name); plugins_count++; } printf("Instanciating output class...\n"); r_output = mrb_gv_get(mrb, output_gv_sym); interval = mrb_fixnum(mrb_funcall(mrb, r_output, "interval", 0)); printf("Interval set to %dms\n", (int)interval); printf("Sending initial report...\n"); mrb_funcall(mrb, r_output, "send_report", 0); if (mrb->exc) { mrb_print_error(mrb); exit(1); } // start all the threads for(i= 0; i< plugins_count; i++){ // printf("== plugin %d\n", i); n = pthread_create(&plugins[i].thread, NULL, plugin_thread, (void *)&plugins[i]); if( n < 0 ){ fprintf(stderr, "create failed\n"); } } if( signal(SIGINT, clean_exit) == SIG_ERR){ perror("signal"); exit(1); } while(running){ int fds[MAX_PLUGINS]; int maxfd = 0, ai; struct timeval tv; mrb_value r_buffer; struct timeval cycle_started_at, cycle_completed_at; gettimeofday(&cycle_started_at, NULL); bzero(fds, sizeof(int) * MAX_PLUGINS); // ask every plugin to send their data for(i= 0; i< plugins_count; i++){ strcpy(buffer, "request"); if( send(plugins[i].host_pipe, buffer, strlen(buffer), 0) == -1 ){ printf("send error when writing in pipe connected to plugin '%s'\n", plugins[i].name); } fds[i] = plugins[i].host_pipe; // printf("sent request to %d\n", i); } // printf("waiting answers...\n"); // and now wait for each answer while(1){ int left = 0; FD_ZERO(&rfds); for(i = 0; i< MAX_PLUGINS; i++){ if( fds[i] != NOPLUGIN_VALUE ){ FD_SET(fds[i], &rfds); left++; if( fds[i] > maxfd ) maxfd = fds[i]; } } // printf("left: %d %d\n", left, left <= 0); if( !running || (0 == left) ) break; // substract 20ms to stay below the loop delay fill_timeout(&tv, cycle_started_at, interval - 20); // printf("before select\n"); n = select(maxfd + 1, &rfds, NULL, NULL, &tv); // printf("after select: %d\n", n); if( n > 0 ){ // find out which pipes have data for(i = 0; i< MAX_PLUGINS; i++){ if( (fds[i] != NOPLUGIN_VALUE) && FD_ISSET(fds[i], &rfds) ){ while (1){ struct timeval answered_at; n = read(fds[i], buffer, sizeof(buffer)); if( n == -1 ){ if( errno != EAGAIN ) perror("read"); break; } if( n == PIPE_BUFFER_SIZE ){ printf("PIPE_BUFFER_SIZE is too small, increase it ! (value: %d)\n", PIPE_BUFFER_SIZE); continue; } gettimeofday(&answered_at, NULL); // printf("received answer from %s in %u ms\n", (const char *) plugins[i].mrb->ud, // (uint32_t)((answered_at.tv_sec - cycle_started_at.tv_sec) * 1000 + // (answered_at.tv_usec - cycle_started_at.tv_usec) / 1000) // ); buffer[n] = 0x00; ai = mrb_gc_arena_save(mrb); r_buffer = mrb_str_buf_new(mrb, n); mrb_str_buf_cat(mrb, r_buffer, buffer, n); // mrb_funcall(mrb, r_output, "tick", 0); mrb_funcall(mrb, r_output, "add", 1, r_buffer); check_exception("add", mrb); // pp(mrb, r_output, 0); mrb_gc_arena_restore(mrb, ai); } fds[i] = 0; } } } else if( n == 0 ) { printf("no responses received from %d plugins.\n", left); break; // timeout } else { perror("select"); } } int idx = mrb_gc_arena_save(mrb); mrb_funcall(mrb, r_output, "flush", 0); check_exception("flush", mrb); mrb_gc_arena_restore(mrb, idx); // and now sleep until the next cycle gettimeofday(&cycle_completed_at, NULL); #ifdef _MEM_PROFILER if( checkpoint_set ){ print_allocations(); } #endif // force a gc run at the end of each cycle mrb_full_gc(mrb); // printf("[main] capa: %d / %d\n", mrb->arena_idx, mrb->arena_capa); // for(i= 0; i< plugins_count; i++){ // printf("[%s] capa: %d / %d\n", plugins[i].name, plugins[i].mrb->arena_idx, plugins[i].mrb->arena_capa); // } #ifdef _MEM_PROFILER checkpoint_set = 1; // and set starting point profiler_set_checkpoint(); #endif #ifdef _MEM_PROFILER_RUBY // dump VMS state dump_state(mrb); for(i= 0; i< plugins_count; i++){ dump_state(plugins[i].mrb); } #endif fflush(stdout); sleep_delay(&cycle_started_at, &cycle_completed_at, interval); } printf("Sending exit signal to all plugins...\n"); strcpy(buffer, "exit"); for(i= 0; i< plugins_count; i++){ C_CHECK("send", send(plugins[i].host_pipe, buffer, strlen(buffer), 0) ); } printf("Giving some time for threads to exit...\n\n"); really_sleep(2000); for(i= 0; i< plugins_count; i++){ int ret = pthread_kill(plugins[i].thread, 0); // if a success is returned then the thread is still alive // which means the thread did not acknoledged the exit message // kill it. if( ret == 0 ){ printf(" - plugin \"%s\" failed to exit properly, killing it...\n", (const char *) plugins[i].mrb->ud); pthread_cancel(plugins[i].thread); } else { printf(" - plugin \"%s\" exited properly.\n", (const char *) plugins[i].mrb->allocf_ud); } if( pthread_join(plugins[i].thread, NULL) < 0){ fprintf(stderr, "join failed\n"); } mrb_close(plugins[i].mrb); } mrb_close(mrb); printf("Exited !\n"); return 0; }
static void rt_incvol(void) { outb(0x98, io); /* volume up + sigstr + on */ sleep_delay(100000); outb(0xd8, io); /* volume steady + sigstr + on */ }
static void rt_incvol(struct rtrack *rt) { outb(0x98, rt->io); /* volume up + sigstr + on */ sleep_delay(100000); outb(0xd8, rt->io); /* volume steady + sigstr + on */ }
static void rt_incvol(struct rtrack *rt) { outb(0x98, rt->io); sleep_delay(100000); outb(0xd8, rt->io); }