static void handle_events(fd_set *rset) { int dev_fd, hotplug_fd; /* handle anything coming through the UNIX socket */ handle_uevents(rset); #ifdef USE_X11 /* handle any X11 events (magellan protocol) */ handle_xevents(rset); #endif /* finally read any pending device input data */ if((dev_fd = get_dev_fd()) != -1) { if(FD_ISSET(dev_fd, rset)) { struct dev_input inp; /* read an event from the device ... */ while(read_dev(&inp) != -1) { /* ... and process it, possibly dispatching a spacenav event to clients */ process_input(&inp); } } } else if((hotplug_fd = get_hotplug_fd()) != -1) { if(FD_ISSET(hotplug_fd, rset)) { handle_hotplug(); } } }
error handle::read(uint32_t addr, void *buf, size_t& sz, bool atomic) { std::unique_lock<std::recursive_mutex> lock(m_mutex); /* get a pointer so that it's not destroyed during the runtime of the function, * the pointer will be released at the end of the function */ std::shared_ptr<context> ctx = m_dev->get_context(); if(!ctx) return error::NO_CONTEXT; /* ensure valid status */ error err = status(); if(err != error::SUCCESS) return err; /* split transfer as needed */ size_t cnt = 0; uint8_t *bufp = (uint8_t *)buf; while(sz > 0) { size_t xfer = std::min(sz, get_buffer_size()); err = read_dev(addr, buf, xfer, atomic); if(err != error::SUCCESS) return err; sz -= xfer; bufp += xfer; addr += xfer; cnt += xfer; } sz = cnt; return error::SUCCESS; }
void *Thread_DebugRx(void* pvParameters){ int8_t u8val; int8_t userinput[33]; int len, userinput_index = 0; sem_t* sem_startup = (sem_t*)pvParameters; fd_set readfs; struct timeval timeout; FD_CLR(g_fd_debug, &readfs); timeout.tv_sec = 0; timeout.tv_usec = 1000*100; // 500ms sem_wait(sem_startup); LREP("Thread DebugRx is running\r\n"); while (1) { len = select(g_fd_debug, &readfs, 0, 0, &timeout); if(len > 0){ if(FD_ISSET(g_fd_debug, &readfs)){ len = read_dev(g_fd_debug, &u8val, 1); if(len > 0){ LREP("%c", u8val); g_debug_cmd = u8val; if(u8val == 'r') reboot(); } }else{ LREP("fd %04X %04X\r\n", g_fd_debug, readfs); } }else if(len == 0){ //LED_TOGGLE(BLUE); } else{ LREP("select uart failed %d.\r\n", len); break; } } while(1){sleep(1);} }
/* Add an entry to a configuration. Return its uniq_mode_t. */ int add_entry(config_t * pconf, char *category, const char *item, int file_index) { if (item[0] == '-' && islower(item[1])) { /* set category */ strcpy(category, item + 1); return 0; } else { /* add to current category */ char str[MAX_STR]; char templat[MAX_TEMPLAT + 1]; const char *pat = 0; string_list_t *list = &pconf->lists.named.resources; if (pconf->debug) printf("Adding %s %s;\n", category, item); /* Handle a few resources specially; just queue the rest. */ switch (category[0]) { #define IS_CAT(str) !strcmp(category, str) case 'c': if (!IS_CAT("comp")) goto err; pat = "compositor_(%scomposite_%%s_type)"; list = &pconf->lists.named.compositors; goto pre; case 'd': if (IS_CAT("dev")) pat = "device_(%s%%s_device)"; else if (IS_CAT("dev2")) pat = "device2_(%s%%s_device)"; else goto err; list = &pconf->lists.named.devs; pre: sprintf(templat, pat, pconf->name_prefix); pat = templat; break; case 'e': if (IS_CAT("emulator")) { sprintf(str, "emulator_(\"%s\",%u)", item, (uint)strlen(item)); item = str; break; } goto err; case 'f': if (IS_CAT("font")) { list = &pconf->lists.named.fonts; break; } else if (IS_CAT("functiontype")) { pat = "function_type_(%%s,%sbuild_function_%%s)"; } else if (IS_CAT("fapi")) { pat = "fapi_(%s%%s_init)"; } else goto err; goto pre; case 'h': if (IS_CAT("halftone")) { pat = "halftone_(%sdht_%%s)"; } else goto err; goto pre; case 'i': if (IS_CAT("imageclass")) { list = &pconf->lists.named.sorted_resources; pat = "image_class_(%simage_class_%%s)"; } else if (IS_CAT("imagetype")) { pat = "image_type_(%%s,%simage_type_%%s)"; } else if (IS_CAT("include")) { strcpy(str, item); dev_file_name(str); return read_dev(pconf, str); } else if (IS_CAT("init")) { pat = "init_(%s%%s_init)"; } else if (IS_CAT("iodev")) { pat = "io_device_(%siodev_%%s)"; } else goto err; goto pre; case 'l': if (IS_CAT("lib")) { list = &pconf->lists.named.libs; break; } else if (IS_CAT("libpath")) { list = &pconf->lists.named.libpaths; break; } else if (IS_CAT("link")) { list = &pconf->lists.named.links; break; } goto err; case 'o': if (IS_CAT("obj")) { list = &pconf->lists.named.objs; strncpy(templat, pconf->file_prefix, MAX_TEMPLAT); strcat(templat, "%s"); pat = templat; break; } if (IS_CAT("oper")) { pat = "oper_(%s_op_defs)"; break; } goto err; case 'p': if (IS_CAT("ps")) { sprintf(str, "psfile_(\"%s.ps\",%u)", item, (uint)(strlen(item) + 3)); item = str; break; } else if (IS_CAT("plugin")) { pat = "plugin_(%s%%s_instantiate)"; goto pre; } goto err; case 'r': if (IS_CAT("replace")) { list = &pconf->replaces; break; } goto err; #undef IS_CAT default: err: fprintf(stderr, "Definition not recognized: %s %s.\n", category, item); exit(1); } if (pat) { sprintf(str, pat, item, item); assert(strlen(str) < MAX_STR); add_item(list, str, file_index); } else add_item(list, item, file_index); return list->mode; } }
int main(int argc, char *argv[]) { config_t conf; char escape = '&'; int i; /* Allocate string lists. */ conf = init_config; memcpy(conf.lists.indexed, init_config_lists, sizeof(conf.lists.indexed)); alloc_list(&conf.file_names); alloc_list(&conf.file_contents); alloc_list(&conf.replaces); for (i = 0; i < NUM_RESOURCE_LISTS; ++i) alloc_list(&conf.lists.indexed[i]); /* Initialize patterns. */ conf.lib_p.upper_case = false; conf.lib_p.drop_extn = false; strcpy(conf.lib_p.pattern, "%s\n"); conf.libpath_p = conf.lib_p; conf.obj_p = conf.lib_p; /* Process command line arguments. */ for (i = 1; i < argc; i++) { const char *arg = argv[i]; FILE *out; int lib = 0, obj = 0; if (*arg != '-') { read_dev(&conf, arg); continue; } if (i == argc - 1) { fprintf(stderr, "Missing argument after %s.\n", arg); exit(1); } switch (arg[1]) { case 'C': /* change directory, by analogy with make */ conf.file_prefix = (argv[i + 1][0] == '-' ? empty_str : argv[i + 1]); ++i; continue; case 'e': escape = argv[i + 1][0]; ++i; continue; case 'n': conf.name_prefix = (argv[i + 1][0] == '-' ? empty_str : argv[i + 1]); ++i; continue; case 'p': { string_pattern_t *pat; switch (*(arg += 2)) { case 'l': pat = &conf.lib_p; break; case 'L': pat = &conf.libpath_p; break; default: pat = &conf.obj_p; arg--; } pat->upper_case = false; pat->drop_extn = false; if (argv[i + 1][0] == '-') strcpy(pat->pattern, "%s\n"); else { char *p, *q; for (p = pat->pattern, q = argv[++i]; (*p++ = *q++) != 0; ) if (p[-1] == escape) switch (*q) { case 'p': p[-1] = '%'; q++; break; case 's': p[-1] = ' '; q++; break; case '-': p[-1] = '-'; q++; break; default: if (*q == escape) { p[-1] = '\\'; q++; break; } fprintf(stderr, "%c not followed by p|s|%c|-: &%c\n", escape, escape, *q); exit(1); } p[-1] = '\n'; *p = 0; } for (;;) { switch (*++arg) { case 'u': pat->upper_case = true; break; case 'e': pat->drop_extn = true; break; case 0: goto pbreak; default: fprintf(stderr, "Unknown switch %s.\n", arg); exit(1); } } pbreak:if (pat == &conf.obj_p) { conf.lib_p = *pat; conf.libpath_p = *pat; } continue; } case 'Z': conf.debug = 1; continue; } /* Must be an output file. */ out = fopen(argv[++i], "w"); if (out == 0) { fprintf(stderr, "Can't open %s for output.\n", argv[i]); exit(1); } switch (arg[1]) { case 'f': process_replaces(&conf); fputs("/* This file was generated automatically by genconf.c. */\n", out); fputs("/* For documentation, see gsconfig.c. */\n", out); { char templat[MAX_TEMPLAT + 1]; sprintf(templat, "font_(\"0.font_%%s\",%sf_%%s,zf_%%s)\n", conf.name_prefix); write_list(out, &conf.lists.named.fonts, templat); } break; case 'h': process_replaces(&conf); fputs("/* This file was generated automatically by genconf.c. */\n", out); write_list(out, &conf.lists.named.compositors, "%s\n"); write_list(out, &conf.lists.named.devs, "%s\n"); sort_uniq(&conf.lists.named.resources, true); write_list(out, &conf.lists.named.resources, "%s\n"); sort_uniq(&conf.lists.named.sorted_resources, false); write_list(out, &conf.lists.named.sorted_resources, "%s\n"); break; case 'l': lib = 1; obj = arg[2] == 'o'; goto lo; case 'o': obj = 1; lib = arg[2] == 'l'; lo:process_replaces(&conf); if (obj) { sort_uniq(&conf.lists.named.objs, true); write_list_pattern(out, &conf.lists.named.objs, &conf.obj_p); } if (lib) { sort_uniq(&conf.lists.named.libs, true); sort_uniq(&conf.lists.named.links, true); write_list_pattern(out, &conf.lists.named.libpaths, &conf.libpath_p); write_list_pattern(out, &conf.lists.named.links, &conf.obj_p); write_list_pattern(out, &conf.lists.named.libs, &conf.lib_p); } break; default: fclose(out); fprintf(stderr, "Unknown switch %s.\n", argv[i]); exit(1); } fclose(out); } free_list(&conf.file_names); free_list(&conf.file_contents); free_list(&conf.replaces); for (i = 0; i < NUM_RESOURCE_LISTS; ++i) free_list(&conf.lists.indexed[i]); return 0; }
/* * Pass the block device location, offset, and data size as the command line arguments. */ int main(const int argc, const char* argv[] ) { if (argc < 5) { fprintf(stderr, "Must pass device path, offset, data size, and o'r' or 'w' as arguments\n"); return -1; } // get block device to use const char* dev = argv[1]; printf("Device is: %s\n", dev); const int offset = atoi(argv[2]); if (offset < 0) { printf("Offset must be > 0\n"); return -1; } printf("Offset is: %d\n", offset); const int size = atoi(argv[3]); if (size < 1) { printf("Size must be greater than 0\n"); return -1; } printf("Data size is: %d\n", size); const char action = argv[4][0]; if (access(dev, R_OK | W_OK) == -1) { // device does not exist perror("Device not found or cannot read/write"); return -1; } // open block device const int f = open(dev, O_RDWR | O_NONBLOCK); if (f < 0) { fprintf(stderr, "Error opening block device %s\n", dev); return -1; } if (action == WRITE) { // write const int c_wrote = write_dev(f, size, offset); if (c_wrote != size) { fprintf(stderr, "Write size did not match requested size\n"); } } else { // read const int c_read = read_dev(f, size, offset); if (c_read != size) { fprintf(stderr, "Read size did not match requested size\n"); } } // The close causes extra reads that will be captured by UART debug // Let the user complete capture before this happens printf("Complete the debug capture, then press any key to close the device file.\nWarning: This will cause extra reads!\n"); getchar(); printf("Closing device\n"); if(close(f) < 0) { perror("Failed to close device file"); } return 0; }
error handle::read_dev(uint32_t addr, void *buf, size_t& sz, bool atomic) { auto p = m_hwdev.lock(); return p ? p->read_dev(addr, buf, sz, atomic) : error::DISCONNECTED; }
int main(int argc, char *argv[]) { int out_fd = -1, use_splice = 1, truncate = O_TRUNC, verboseness = 0; char *buf = NULL, *dev_path = DEV_PATH, *out_path = NULL; int restart_requested, dev_fd, pipe_in, pipe_out, pipe_fd[2]; ssize_t n, m; unsigned int snaplen = 0, buflen = 8192; ssize_t (*read_dev)(void); ssize_t (*write_out)(void); struct argp_option options[] = { {"append", 'a', 0, 0, "append new records instead of overwriting"}, {"device", 'd', "DEVICE", 0, "read events from DEVICE (default: " DEV_PATH ")"}, {"buflen", 'l', "BYTES", 0, "set buffer length; implies -n (default: 8192)"}, {"no-splice", 'n', 0, 0, "use read()/write() instead of splice"}, {"quiet", 'q', 0, 0, "decrease verboseness of debug output"}, {"snaplen", 's', "BYTES", 0, "set maximum packet capture size to BYTES bytes"}, {"verbose", 'v', 0, 0, "increase verboseness of debug output"}, {0}, }; error_t parse_opt(int key, char *arg, struct argp_state *state) { switch (key) { case 'a': truncate = 0; break; case 'd': dev_path = arg; break; case 'l': if (parse_unsigned_int(&buflen, arg)) argp_error(state, "invalid buflen: %s\n", arg); use_splice = 0; break; case 'n': use_splice = 0; break; case 'q': verboseness--; break; case 's': if (parse_unsigned_int(&snaplen, arg)) argp_error(state, "invalid snaplen: %s\n", arg); break; case 'v': verboseness++; break; case ARGP_KEY_ARG: if (!state->arg_num) out_path = arg; else return ARGP_ERR_UNKNOWN; break; default: return ARGP_ERR_UNKNOWN; } return 0; } struct argp argp = {options, parse_opt, "[OUTPUT_FILE]", "Read Hone events and write to a file or standard output.", NULL, NULL, NULL}; if (argp_parse(&argp, argc, argv, 0, NULL, NULL)) err(EX_OSERR, "argp_parse() failed"); if (verboseness > 0) verbose1 = log_stderr; if (verboseness > 1) verbose2 = log_stderr; if (verboseness > 2) verbose3 = log_stderr; verbose2("Options:\n"); verbose2(" buffer size: "); if (use_splice) verbose2("unused\n"); else verbose2("%u\n", buflen); verbose2(" input device: %s\n", dev_path); verbose2(" output file: %s\n", out_path ?: "<standard output>"); verbose2(" snaplen: %u\n", snaplen); verbose2(" use splice: %s\n", use_splice ? "yes" : "no"); verbose2(" verbosity level: %d\n", verboseness); if (verboseness > 3) err(EX_USAGE, "verboseness limit exceeded"); signal(SIGHUP, sighandler); signal(SIGINT, sighandler); signal(SIGTERM, sighandler); ssize_t splice_read(void) { return splice(dev_fd, NULL, pipe_in, NULL, 65536, 0); } ssize_t splice_write(void) { return splice(pipe_out, NULL, out_fd, NULL, n, 0); } ssize_t conventional_read(void) { return read(dev_fd, buf, buflen); } ssize_t conventional_write(void) { return write(out_fd, buf, n); } if (use_splice) { if (pipe(pipe_fd)) err(EX_OSERR, "pipe() failed"); pipe_out = pipe_fd[0]; pipe_in = pipe_fd[1]; read_dev = splice_read; write_out = splice_write; } else { if (!(buf = (typeof(buf)) malloc(buflen))) err(EX_OSERR, "malloc() failed"); read_dev = conventional_read; write_out = conventional_write; } if ((dev_fd = open(dev_path, O_RDONLY, 0)) == -1) err(EX_NOINPUT, "open() failed on %s", dev_path); if (snaplen && ioctl(dev_fd, HEIO_SET_SNAPLEN, snaplen) == -1) err(EX_IOERR, "set snaplen ioctl() failed"); void close_out(void) { if (close(out_fd)) err(EX_OSERR, "close() failed on %s", out_path); out_fd = -1; } restart: restart = 0; restart_requested = 0; if (out_fd != -1) close_out(); if (!out_path || !strcmp(out_path, "-")) { if ((out_fd = dup(STDOUT_FILENO)) == -1) err(EX_CANTCREAT, "dup() failed on stdout"); } else { if ((out_fd = open(out_path, O_WRONLY | O_CREAT | O_LARGEFILE | truncate, 00664)) == -1) err(EX_CANTCREAT, "open() failed on %s", out_path); if (!truncate && lseek(out_fd, 0, SEEK_END) == (off_t) -1) err(EX_OSERR, "error seeking to end of output file"); } if (use_splice) { int is_fifo = 0; struct stat st; if (fstat(out_fd, &st)) warn("fstat() failed"); else is_fifo = S_ISFIFO(st.st_mode); pipe_in = is_fifo ? out_fd : pipe_fd[1]; verbose2("output file is%s a FIFO\n", is_fifo ? "" : " not"); } for (;;) { if ((restart || done) && !restart_requested) { if (ioctl(dev_fd, HEIO_RESTART) == -1) err(EX_OSERR, "reset ioctl() failed"); verbose1("Requesting device restart.\n"); restart_requested = 1; } if ((n = read_dev()) == -1) { if (errno != EINTR && errno != EAGAIN) err(EX_OSERR, "reading from device failed"); continue; } if (!n) { verbose1("Device restarted.\n"); if (done || ioctl(dev_fd, HEIO_GET_AT_HEAD) <= 0) break; verbose1("Reopening output file.\n"); goto restart; } verbose3("Read %ld bytes\n", n); if (out_fd == pipe_in) /* spliced directly to FIFO */ continue; while (n > 0) { if ((m = write_out()) == -1) { if (errno != EINTR && errno != EAGAIN) err(EX_OSERR, "writing to output failed"); continue; } verbose3("Wrote %ld bytes\n", m); n -= m; } } close_out(); close(dev_fd); close(pipe_fd[0]); close(pipe_fd[1]); free(buf); exit(EX_OK); }