/** * @brief Main function logic * * Parse command line options and start running threads */ int main(int argc, char* argv[]) { int opt, idx, limit, only_calls, no_incomplete, i; const char *device, *outfile; char bpf[512]; const char *keyfile; const char *match_expr; int match_insensitive = 0, match_invert = 0; int no_interface = 0, quiet = 0, rtp_capture = 0; vector_t *infiles = vector_create(0, 1); // Program otptions static struct option long_options[] = { { "help", no_argument, 0, 'h' }, { "version", no_argument, 0, 'V' }, { "device", required_argument, 0, 'd' }, { "input", required_argument, 0, 'I' }, { "output", required_argument, 0, 'O' }, #if defined(WITH_GNUTLS) || defined(WITH_OPENSSL) { "keyfile", required_argument, 0, 'k' }, #endif { "calls", no_argument, 0, 'c' }, { "rtp", no_argument, 0, 'r' }, { "limit", no_argument, 0, 'l' }, { "icase", no_argument, 0, 'i' }, { "invert", no_argument, 0, 'v' }, { "no-interface", no_argument, 0, 'N' }, { "dump-config", no_argument, 0, 'D' }, #ifdef USE_EEP { "eep-listen", required_argument, 0, 'L' }, { "eep-send", required_argument, 0, 'H' }, #endif { "quiet", no_argument, 0, 'q' }, }; // Initialize configuration options init_options(); // Get initial values for configurable arguments device = setting_get_value(SETTING_CAPTURE_DEVICE); outfile = setting_get_value(SETTING_CAPTURE_OUTFILE); keyfile = setting_get_value(SETTING_CAPTURE_KEYFILE); limit = setting_get_intvalue(SETTING_CAPTURE_LIMIT); only_calls = setting_enabled(SETTING_SIP_CALLS); no_incomplete = setting_enabled(SETTING_SIP_NOINCOMPLETE); rtp_capture = setting_enabled(SETTING_CAPTURE_RTP); // Parse command line arguments opterr = 0; char *options = "hVd:I:O:pqtW:k:crl:ivNqDL:H:"; while ((opt = getopt_long(argc, argv, options, long_options, &idx)) != -1) { switch (opt) { case 'h': usage(); return 0; case 'V': version(); return 0; case 'd': device = optarg; break; case 'I': vector_append(infiles, optarg); break; case 'O': outfile = optarg; break; case 'l': if(!(limit = atoi(optarg))) { fprintf(stderr, "Invalid limit value.\n"); return 0; } break; #if defined(WITH_GNUTLS) || defined(WITH_OPENSSL) case 'k': keyfile = optarg; break; #endif case 'c': only_calls = 1; setting_set_value(SETTING_SIP_CALLS, SETTING_ON); break; case 'r': rtp_capture = 1; setting_set_value(SETTING_CAPTURE_RTP, SETTING_ON); break; case 'i': match_insensitive++; break; case 'v': match_invert++; break; case 'N': no_interface = 1; setting_set_value(SETTING_CAPTURE_STORAGE, "none"); break; case 'q': quiet = 1; break; case 'D': key_bindings_dump(); settings_dump(); return 0; // Dark options for dummy ones case 'p': case 't': case 'W': break; #ifdef USE_EEP case 'L': capture_eep_set_server_url(optarg); break; case 'H': capture_eep_set_client_url(optarg); break; #endif case '?': if (strchr(options, optopt)) { fprintf(stderr, "-%c option requires an argument.\n", optopt); } else if (isprint(optopt)) { fprintf(stderr, "Unknown option -%c.\n", optopt); } else { fprintf(stderr, "Unknown option character '\\x%x'.\n", optopt); } return 1; default: break; } } #if defined(WITH_GNUTLS) || defined(WITH_OPENSSL) // Set capture decrypt key file capture_set_keyfile(keyfile); // Check if we have a keyfile and is valid if (keyfile && !tls_check_keyfile(keyfile)) { fprintf(stderr, "%s does not contain a valid RSA private key.\n", keyfile); return 1; } #endif // Check if given argument is a file if (argc == 2 && (access(argv[1], F_OK) == 0)) { // Old legacy option to open pcaps without other arguments printf("%s seems to be a file: You forgot -I flag?\n", argv[1]); return 0; } // Initialize SIP Messages Storage sip_init(limit, only_calls, no_incomplete); // Set capture options capture_init(limit, rtp_capture); #ifdef USE_EEP // Initialize EEP if enabled capture_eep_init(); #endif // If we have an input file, load it if (vector_count(infiles)) { for (i = 0; i < vector_count(infiles); i++) { // Try to load file if (capture_offline(vector_item(infiles, i), outfile) != 0) return 1; } } else { // Check if all capture data is valid if (capture_online(device, outfile) != 0) return 1; } // Remove Input files vector vector_destroy(infiles); // More arguments pending! if (argv[optind]) { // Assume first pending argument is match expression match_expr = argv[optind++]; // Try to build the bpf filter string with the rest memset(bpf, 0, sizeof(bpf)); for (i = optind; i < argc; i++) sprintf(bpf + strlen(bpf), "%s ", argv[i]); // Check if this BPF filter is valid if (capture_set_bpf_filter(bpf) != 0) { // BPF Filter invalid, check incluiding match_expr match_expr = 0; // There is no need to parse all payload at this point // Build the bpf filter string memset(bpf, 0, sizeof(bpf)); for (i = optind - 1; i < argc; i++) sprintf(bpf + strlen(bpf), "%s ", argv[i]); // Check bpf filter is valid again if (capture_set_bpf_filter(bpf) != 0) { fprintf(stderr, "Couldn't install filter %s: %s\n", bpf, capture_last_error()); return 1; } } // Set the capture filter if (match_expr) if (sip_set_match_expression(match_expr, match_insensitive, match_invert)) { fprintf(stderr, "Unable to parse expression %s\n", match_expr); return 1; } } // Start a capture thread if (capture_launch_thread() != 0) { ncurses_deinit(); fprintf(stderr, "Failed to launch capture thread.\n"); return 1; } if (!no_interface) { // Initialize interface ncurses_init(); // This is a blocking call. // Create the first panel and wait for user input ui_create_panel(PANEL_CALL_LIST); wait_for_input(); } else { setbuf(stdout, NULL); while(capture_get_status() != CAPTURE_OFFLINE) { if (!quiet) printf("\rDialog count: %d", sip_calls_count()); usleep(500 * 1000); } if (!quiet) printf("\rDialog count: %d\n", sip_calls_count()); } // Capture deinit capture_deinit(); // Deinitialize interface ncurses_deinit(); // Deinitialize configuration options deinit_options(); // Deallocate sip stored messages sip_deinit(); // Leaving! return 0; }
int main(int argc, char *argv[]) { /** return value of main() */ int res = 1; /* current configuration */ LedPrefs *prefs = NULL; /* current setup */ LedSetup *setup = NULL; /** framebuffer for captured image */ LedFrame *frame = NULL; /* check binary version compatibility */ NFT_LED_CHECK_VERSION /* set default loglevel to INFO */ nft_log_level_set(L_INFO); /* initialize exit handlers */ int signals[] = { SIGHUP, SIGINT, SIGQUIT, SIGABRT }; unsigned int i; for(i=0; i<sizeof(signals)/sizeof(int); i++) { if(signal(signals[i], _exit_signal_handler) == SIG_ERR) { NFT_LOG_PERROR("signal()"); goto _m_exit; } } /* default fps */ _c.fps = 25; /* default mechanism */ _c.method = METHOD_MIN+1; /* default config-filename */ if(!led_prefs_default_filename(_c.prefsfile, sizeof(_c.prefsfile), ".ledcap.xml")) goto _m_exit; /* parse cmdline-arguments */ if(!_parse_args(argc, argv)) goto _m_exit; /* print welcome msg */ NFT_LOG(L_INFO, "%s %s (c) D.Hiepler 2006-2012", PACKAGE_NAME, ledcap_version_long()); NFT_LOG(L_VERBOSE, "Loglevel: %s", nft_log_level_to_string(nft_log_level_get())); /* initialize preferences context */ if(!(prefs = led_prefs_init())) return -1; /* parse prefs-file */ LedPrefsNode *pnode; if(!(pnode = led_prefs_node_from_file(_c.prefsfile))) { NFT_LOG(L_ERROR, "Failed to open configfile \"%s\"", _c.prefsfile); goto _m_exit; } /* create setup from prefs-node */ if(!(setup = led_prefs_setup_from_node(prefs, pnode))) { NFT_LOG(L_ERROR, "No valid setup found in preferences file."); led_prefs_node_free(pnode); goto _m_exit; } /* free preferences node */ led_prefs_node_free(pnode); /* determine width of input-frames */ LedFrameCord width, height; if((width = led_setup_get_width(setup)) > _c.width) { NFT_LOG(L_WARNING, "LED-Setup width (%d) > our width (%d). Using setup-value", width,_c.width); /* use dimensions of mapped chain */ _c.width = width; } /* determine height of input-frames */ if((height = led_setup_get_height(setup)) > _c.height) { NFT_LOG(L_WARNING, "LED-Setup height (%d) > our height (%d). Using setup-value.", height, _c.height); /* use dimensions of mapped chain */ _c.height = height; } if(_c.width < 0) { NFT_LOG(L_ERROR, "width (%d) < 0", _c.width); goto _m_exit; } if(_c.height < 0) { NFT_LOG(L_ERROR, "height (%d) < 0", _c.height); goto _m_exit; } /* sanitize x-offset @todo check for maximum */ if(_c.x < 0) { NFT_LOG(L_ERROR, "Invalid x coordinate: %d, using 0", _c.x); _c.x = 0; } /* sanitize y-offset @todo check for maximum */ if(_c.y < 0) { NFT_LOG(L_ERROR, "Invalid y coordinate: %d, using 0", _c.y); _c.y = 0; } /* initialize capture mechanism (only imlib for now) */ if(!capture_init(_c.method)) goto _m_exit; /* allocate framebuffer */ NFT_LOG(L_INFO, "Allocating frame: %dx%d (%s)", _c.width, _c.height, capture_format()); if(!(frame = led_frame_new(_c.width, _c.height, led_pixel_format_from_string(capture_format())))) goto _m_exit; /* respect endianess */ led_frame_set_big_endian(frame, capture_is_big_endian()); /* get first hardware */ LedHardware *hw; if(!(hw = led_setup_get_hardware(setup))) goto _m_exit; /* initialize pixel->led mapping */ if(!led_hardware_list_refresh_mapping(hw)) goto _m_exit; /* precalc memory offsets for actual mapping */ if(!led_chain_map_from_frame(led_hardware_get_chain(hw), frame)) goto _m_exit; /* set saved gain to all registered hardware instances */ if(!led_hardware_list_refresh_gain(hw)) goto _m_exit; /* print some debug-info */ led_frame_print(frame, L_VERBOSE); led_hardware_print(hw, L_VERBOSE); /* initially sample time for frametiming */ if(!led_fps_sample()) goto _m_exit; /* output some useful info */ NFT_LOG(L_INFO, "Capturing %dx%d pixels at position x/y: %d/%d", _c.width, _c.height, _c.x, _c.y); /* loop until _c.running is set to FALSE */ _c.running = TRUE; while(_c.running) { /* capture frame */ if(!(capture_frame(frame, _c.x, _c.y))) break; /* print frame for debugging */ //led_frame_buffer_print(frame); /* map from frame */ LedHardware *h; for(h = hw; h; h = led_hardware_list_get_next(h)) { if(!led_chain_fill_from_frame(led_hardware_get_chain(h), frame)) { NFT_LOG(L_ERROR, "Error while mapping frame"); break; } } /* send frame to hardware(s) */ led_hardware_list_send(hw); /* delay in respect to fps */ if(!led_fps_delay(_c.fps)) break; /* show frame */ led_hardware_list_show(hw); /* save time when frame is displayed */ if(!led_fps_sample()) break; } /* mark success */ res = 0; _m_exit: /* deinitialize capture mechanism */ capture_deinit(); /* free frame */ led_frame_destroy(frame); /* destroy config */ led_setup_destroy(setup); /* destroy config */ led_prefs_deinit(prefs); return res; }