示例#1
0
/*
 * Parse program arguments
 */
static int parse_args(pj_pool_t *pool, int argc, char *argv[])
{
    int c;
    int option_index;
    enum { OPT_CONFIG_FILE, OPT_LOG_FILE, OPT_LOG_LEVEL, OPT_APP_LOG_LEVEL, 
	   OPT_HELP, OPT_VERSION, OPT_NULL_AUDIO,
	   OPT_LOCAL_PORT, OPT_PROXY, OPT_OUTBOUND_PROXY, OPT_REGISTRAR,
	   OPT_REG_TIMEOUT, OPT_ID, OPT_CONTACT, 
	   OPT_REALM, OPT_USERNAME, OPT_PASSWORD,
	   OPT_USE_STUN1, OPT_USE_STUN2, 
	   OPT_ADD_BUDDY, OPT_OFFER_X_MS_MSG, OPT_NO_PRESENCE,
	   OPT_AUTO_ANSWER, OPT_AUTO_HANGUP};
    struct option long_options[] = {
	{ "config-file",1, 0, OPT_CONFIG_FILE},
	{ "log-file",	1, 0, OPT_LOG_FILE},
	{ "log-level",	1, 0, OPT_LOG_LEVEL},
	{ "app-log-level",1,0,OPT_APP_LOG_LEVEL},
	{ "help",	0, 0, OPT_HELP},
	{ "version",	0, 0, OPT_VERSION},
	{ "null-audio", 0, 0, OPT_NULL_AUDIO},
	{ "local-port", 1, 0, OPT_LOCAL_PORT},
	{ "proxy",	1, 0, OPT_PROXY},
	{ "outbound",	1, 0, OPT_OUTBOUND_PROXY},
	{ "registrar",	1, 0, OPT_REGISTRAR},
	{ "reg-timeout",1, 0, OPT_REG_TIMEOUT},
	{ "id",		1, 0, OPT_ID},
	{ "contact",	1, 0, OPT_CONTACT},
	{ "realm",	1, 0, OPT_REALM},
	{ "username",	1, 0, OPT_USERNAME},
	{ "password",	1, 0, OPT_PASSWORD},
	{ "use-stun1",  1, 0, OPT_USE_STUN1},
	{ "use-stun2",  1, 0, OPT_USE_STUN2},
	{ "add-buddy",  1, 0, OPT_ADD_BUDDY},
	{ "offer-x-ms-msg",0,0,OPT_OFFER_X_MS_MSG},
	{ "no-presence", 0, 0, OPT_NO_PRESENCE},
	{ "auto-answer",1, 0, OPT_AUTO_ANSWER},
	{ "auto-hangup",1, 0, OPT_AUTO_HANGUP},
	{ NULL, 0, 0, 0}
    };
    char *config_file = NULL;

    /* Run getopt once to see if user specifies config file to read. */
    while ((c=getopt_long(argc, argv, "", long_options, &option_index)) != -1) {
	switch (c) {
	case 0:
	    config_file = optarg;
	    break;
	}
	if (config_file)
	    break;
    }

    if (config_file) {
	if (read_config_file(pool, config_file, &argc, &argv) != 0)
	    return -1;
    }

    /* Reinitialize and re-run getopt again, possibly with new arguments
     * read from config file.
     */
    optind = 0;
    while ((c=getopt_long(argc, argv, "", long_options, &option_index)) != -1) {
	char *err, *p;

	switch (c) {
	case OPT_LOG_FILE:
	    global.log_filename = optarg;
	    break;
	case OPT_LOG_LEVEL:
	    c = strtoul(optarg, &err, 10);
	    if (*err) {
		printf("Error: expecting integer value 0-6 for --log-level\n");
		return -1;
	    }
	    pj_log_set_level( c );
	    break;
	case OPT_APP_LOG_LEVEL:
	    global.app_log_level = strtoul(optarg, &err, 10);
	    if (*err) {
		printf("Error: expecting integer value 0-6 for --app-log-level\n");
		return -1;
	    }
	    break;
	case OPT_HELP:
	    usage();
	    return -1;
	case OPT_VERSION:   /* version */
	    pj_dump_config();
	    return -1;
	case OPT_NULL_AUDIO:
	    global.null_audio = 1;
	    break;
	case OPT_LOCAL_PORT:   /* local-port */
	    global.sip_port = strtoul(optarg, &err, 10);
	    if (*err) {
		printf("Error: expecting integer value for --local-port\n");
		return -1;
	    }
	    break;
	case OPT_PROXY:   /* proxy */
	    if (verify_sip_url(optarg) != 0) {
		printf("Error: invalid SIP URL '%s' in proxy argument\n", optarg);
		return -1;
	    }
	    global.proxy = pj_str(optarg);
	    break;
	case OPT_OUTBOUND_PROXY:   /* outbound proxy */
	    if (verify_sip_url(optarg) != 0) {
		printf("Error: invalid SIP URL '%s' in outbound proxy argument\n", optarg);
		return -1;
	    }
	    global.outbound_proxy = pj_str(optarg);
	    break;
	case OPT_REGISTRAR:   /* registrar */
	    if (verify_sip_url(optarg) != 0) {
		printf("Error: invalid SIP URL '%s' in registrar argument\n", optarg);
		return -1;
	    }
	    global.registrar_uri = pj_str(optarg);
	    break;
	case OPT_REG_TIMEOUT:   /* reg-timeout */
	    global.reg_timeout = strtoul(optarg, &err, 10);
	    if (*err) {
		printf("Error: expecting integer value for --reg-timeout\n");
		return -1;
	    }
	    break;
	case OPT_ID:   /* id */
	    if (verify_sip_url(optarg) != 0) {
		printf("Error: invalid SIP URL '%s' in local id argument\n", optarg);
		return -1;
	    }
	    global.local_uri = pj_str(optarg);
	    break;
	case OPT_CONTACT:   /* contact */
	    if (verify_sip_url(optarg) != 0) {
		printf("Error: invalid SIP URL '%s' in contact argument\n", optarg);
		return -1;
	    }
	    global.contact = pj_str(optarg);
	    break;
	case OPT_USERNAME:   /* Default authentication user */
	    if (!global.cred_count) global.cred_count = 1;
	    global.cred_info[0].username = pj_str(optarg);
	    break;
	case OPT_REALM:	    /* Default authentication realm. */
	    if (!global.cred_count) global.cred_count = 1;
	    global.cred_info[0].realm = pj_str(optarg);
	    break;
	case OPT_PASSWORD:   /* authentication password */
	    if (!global.cred_count) global.cred_count = 1;
	    global.cred_info[0].data_type = 0;
	    global.cred_info[0].data = pj_str(optarg);
	    break;
	case OPT_USE_STUN1:   /* STUN server 1 */
	    p = strchr(optarg, ':');
	    if (p) {
		*p = '\0';
		global.stun_srv1 = pj_str(optarg);
		global.stun_port1 = strtoul(p+1, &err, 10);
		if (*err || global.stun_port1==0) {
		    printf("Error: expecting port number with option --use-stun1\n");
		    return -1;
		}
	    } else {
		global.stun_port1 = 3478;
		global.stun_srv1 = pj_str(optarg);
	    }
	    break;
	case OPT_USE_STUN2:   /* STUN server 2 */
	    p = strchr(optarg, ':');
	    if (p) {
		*p = '\0';
		global.stun_srv2 = pj_str(optarg);
		global.stun_port2 = strtoul(p+1, &err, 10);
		if (*err || global.stun_port2==0) {
		    printf("Error: expecting port number with option --use-stun2\n");
		    return -1;
		}
	    } else {
		global.stun_port2 = 3478;
		global.stun_srv2 = pj_str(optarg);
	    }
	    break;
	case OPT_ADD_BUDDY: /* Add to buddy list. */
	    if (verify_sip_url(optarg) != 0) {
		printf("Error: invalid URL '%s' in --add-buddy option\n", optarg);
		return -1;
	    }
	    if (global.buddy_cnt == MAX_BUDDIES) {
		printf("Error: too many buddies in buddy list.\n");
		return -1;
	    }
	    global.buddy[global.buddy_cnt++] = pj_str(optarg);
	    break;
	case OPT_OFFER_X_MS_MSG:
	    global.offer_x_ms_msg = 1;
	    break;
	case OPT_NO_PRESENCE:
	    global.no_presence = 1;
	    break;
	case OPT_AUTO_ANSWER:
	    global.auto_answer = strtoul(optarg, &err, 10);
	    if (*err) {
		printf("Error: expecting integer value for --auto-answer option\n");
		return -1;
	    }
	    break;
	case OPT_AUTO_HANGUP:
	    global.auto_hangup = strtoul(optarg, &err, 10);
	    if (*err) {
		printf("Error: expecting integer value for --auto-hangup option\n");
		return -1;
	    }
	    break;
	}
    }

    if (optind != argc) {
	printf("Error: unknown options %s\n", argv[optind]);
	return -1;
    }

    if (global.reg_timeout == 0)
	global.reg_timeout = 3600;

    return 0;
}
static pj_status_t init_options(int argc, char *argv[])
{
    enum { OPT_THREAD_COUNT = 1, OPT_REAL_SDP, OPT_TRYING, OPT_RINGING };
    struct pj_getopt_option long_options[] = {
	{ "local-port",	    1, 0, 'p' },
	{ "count",	    1, 0, 'c' },
	{ "thread-count",   1, 0, OPT_THREAD_COUNT },
	{ "method",	    1, 0, 'm' },
	{ "help",	    0, 0, 'h' },
	{ "stateless",	    0, 0, 's' },
	{ "timeout",	    1, 0, 't' },
	{ "real-sdp",	    0, 0, OPT_REAL_SDP },
	{ "verbose",        0, 0, 'v' },
	{ "use-tcp",	    0, 0, 'T' },
	{ "window",	    1, 0, 'w' },
	{ "delay",	    1, 0, 'd' },
	{ "trying",	    0, 0, OPT_TRYING},
	{ "ringing",	    0, 0, OPT_RINGING},
	{ NULL, 0, 0, 0 },
    };
    int c;
    int option_index;

    /* Init default application configs */
    app.local_port = 5060;
    app.thread_count = 1;
    app.client.job_count = DEFAULT_COUNT;
    app.client.method = *pjsip_get_options_method();
    app.client.job_window = c = JOB_WINDOW;
    app.client.timeout = 60;
    app.log_level = 3;


    /* Parse options */
    pj_optind = 0;
    while((c=pj_getopt_long(argc,argv, "p:c:m:t:w:d:hsv", 
			    long_options, &option_index))!=-1) 
    {
	switch (c) {
	case 'p':
	    app.local_port = my_atoi(pj_optarg);
	    if (app.local_port < 0 || app.local_port > 65535) {
		PJ_LOG(3,(THIS_FILE, "Invalid --local-port %s", pj_optarg));
		return -1;
	    }
	    break;

	case 'c':
	    app.client.job_count = my_atoi(pj_optarg);
	    if (app.client.job_count < 0) {
		PJ_LOG(3,(THIS_FILE, "Invalid --local-port %s", pj_optarg));
		return -1;
	    }
	    if (app.client.job_count > pjsip_cfg()->tsx.max_count)
		PJ_LOG(3,(THIS_FILE, 
			  "Warning: --count value (%d) exceeds maximum "
			  "transaction count (%d)", app.client.job_count,
			  pjsip_cfg()->tsx.max_count));
	    break;

	case OPT_THREAD_COUNT:
	    app.thread_count = my_atoi(pj_optarg);
	    if (app.thread_count < 1 || app.thread_count > 16) {
		PJ_LOG(3,(THIS_FILE, "Invalid --thread-count %s", pj_optarg));
		return -1;
	    }
	    break;

	case 'm':
	    {
		pj_str_t temp = pj_str((char*)pj_optarg);
		pjsip_method_init_np(&app.client.method, &temp);
	    }
	    break;

	case 'h':
	    usage();
	    return -1;

	case 's':
	    app.client.stateless = PJ_TRUE;
	    break;

	case OPT_REAL_SDP:
	    app.real_sdp = 1;
	    break;

	case 'v':
	    app.log_level++;
	    break;

	case 't':
	    app.client.timeout = my_atoi(pj_optarg);
	    if (app.client.timeout < 0 || app.client.timeout > 600) {
		PJ_LOG(3,(THIS_FILE, "Invalid --timeout %s", pj_optarg));
		return -1;
	    }
	    break;

	case 'w':
	    app.client.job_window = my_atoi(pj_optarg);
	    if (app.client.job_window <= 0) {
		PJ_LOG(3,(THIS_FILE, "Invalid --window %s", pj_optarg));
		return -1;
	    }
	    break;

	case 'T':
	    app.use_tcp = PJ_TRUE;
	    break;

	case 'd':
	    app.server.delay = my_atoi(pj_optarg);
	    if (app.server.delay > 3600) {
		PJ_LOG(3,(THIS_FILE, "I think --delay %s is too long", 
			  pj_optarg));
		return -1;
	    }
	    break;

	case OPT_TRYING:
	    app.server.send_trying = 1;
	    break;

	case OPT_RINGING:
	    app.server.send_ringing = 1;
	    break;

	default:
	    PJ_LOG(1,(THIS_FILE, 
		      "Invalid argument. Use --help to see help"));
	    return -1;
	}
    }

    if (pj_optind != argc) {

	if (verify_sip_url(argv[pj_optind]) != PJ_SUCCESS) {
	    PJ_LOG(1,(THIS_FILE, "Invalid SIP URI %s", argv[pj_optind]));
	    return -1;
	}
	app.client.dst_uri = pj_str(argv[pj_optind]);
	
	pj_optind++;

    }

    if (pj_optind != argc) {
	PJ_LOG(1,(THIS_FILE, "Error: unknown options %s", argv[pj_optind]));
	return -1;
    }

    return 0;
}