⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pjsua_app.c

📁 一个开源的sip源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
}


/*
 * Input simple string
 */
static pj_bool_t simple_input(const char *title, char *buf, pj_size_t len)
{
    char *p;

    printf("%s (empty to cancel): ", title); fflush(stdout);
    fgets(buf, len, stdin);

    /* Remove trailing newlines. */
    for (p=buf; ; ++p) {
	if (*p=='\r' || *p=='\n') *p='\0';
	else if (!*p) break;
    }

    if (!*buf)
	return PJ_FALSE;
    
    return PJ_TRUE;
}


#define NO_NB	-2
struct input_result
{
    int	  nb_result;
    char *uri_result;
};


/*
 * Input URL.
 */
static void ui_input_url(const char *title, char *buf, int len, 
			 struct input_result *result)
{
    result->nb_result = NO_NB;
    result->uri_result = NULL;

    print_buddy_list();

    printf("Choices:\n"
	   "   0         For current dialog.\n"
	   "  -1         All %d buddies in buddy list\n"
	   "  [1 -%2d]    Select from buddy list\n"
	   "  URL        An URL\n"
	   "  <Enter>    Empty input (or 'q') to cancel\n"
	   , pjsua_get_buddy_count(), pjsua_get_buddy_count());
    printf("%s: ", title);

    fflush(stdout);
    fgets(buf, len, stdin);
    len = strlen(buf);

    /* Left trim */
    while (pj_isspace(*buf)) {
	++buf;
	--len;
    }

    /* Remove trailing newlines */
    while (len && (buf[len-1] == '\r' || buf[len-1] == '\n'))
	buf[--len] = '\0';

    if (len == 0 || buf[0]=='q')
	return;

    if (pj_isdigit(*buf) || *buf=='-') {
	
	int i;
	
	if (*buf=='-')
	    i = 1;
	else
	    i = 0;

	for (; i<len; ++i) {
	    if (!pj_isdigit(buf[i])) {
		puts("Invalid input");
		return;
	    }
	}

	result->nb_result = my_atoi(buf);

	if (result->nb_result >= 0 && 
	    result->nb_result <= (int)pjsua_get_buddy_count()) 
	{
	    return;
	}
	if (result->nb_result == -1)
	    return;

	puts("Invalid input");
	result->nb_result = NO_NB;
	return;

    } else {
	pj_status_t status;

	if ((status=pjsua_verify_sip_url(buf)) != PJ_SUCCESS) {
	    pjsua_perror(THIS_FILE, "Invalid URL", status);
	    return;
	}

	result->uri_result = buf;
    }
}

/*
 * List the ports in conference bridge
 */
static void conf_list(void)
{
    unsigned i, count;
    pjsua_conf_port_id id[PJSUA_MAX_CALLS];

    printf("Conference ports:\n");

    count = PJ_ARRAY_SIZE(id);
    pjsua_enum_conf_ports(id, &count);

    for (i=0; i<count; ++i) {
	char txlist[PJSUA_MAX_CALLS*4+10];
	unsigned j;
	pjsua_conf_port_info info;

	pjsua_conf_get_port_info(id[i], &info);

	txlist[0] = '\0';
	for (j=0; j<info.listener_cnt; ++j) {
	    char s[10];
	    pj_ansi_sprintf(s, "#%d ", info.listeners[j]);
	    pj_ansi_strcat(txlist, s);
	}
	printf("Port #%02d[%2dKHz/%dms] %20.*s  transmitting to: %s\n", 
	       info.slot_id, 
	       info.clock_rate/1000,
	       info.samples_per_frame * 1000 / info.clock_rate,
	       (int)info.name.slen, 
	       info.name.ptr,
	       txlist);

    }
    puts("");
}


/*
 * Send arbitrary request to remote host
 */
static void send_request(char *cstr_method, const pj_str_t *dst_uri)
{
    pj_str_t str_method;
    pjsip_method method;
    pjsip_tx_data *tdata;
    pjsip_endpoint *endpt;
    pj_status_t status;

    endpt = pjsua_get_pjsip_endpt();

    str_method = pj_str(cstr_method);
    pjsip_method_init_np(&method, &str_method);

    status = pjsua_acc_create_request(current_acc, &method, dst_uri, &tdata);

    status = pjsip_endpt_send_request(endpt, tdata, -1, NULL, NULL);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to send request", status);
	return;
    }
}


/*
 * Main "user interface" loop.
 */
void console_app_main(const pj_str_t *uri_to_call)
{
    char menuin[32];
    char buf[128];
    char text[128];
    int i, count;
    char *uri;
    pj_str_t tmp;
    struct input_result result;
    pjsua_call_info call_info;
    pjsua_acc_info acc_info;


    /* If user specifies URI to call, then call the URI */
    if (uri_to_call->slen) {
	pjsua_call_make_call( current_acc, uri_to_call, 0, NULL, NULL, NULL);
    }

    keystroke_help();

    for (;;) {

	printf(">>> ");
	fflush(stdout);

	if (fgets(menuin, sizeof(menuin), stdin) == NULL) {
	    /* 
	     * Be friendly to users who redirect commands into
	     * program, when file ends, resume with kbd.
	     * If exit is desired end script with q for quit
	     */
 	    /* Reopen stdin/stdout/stderr to /dev/console */
#if defined(PJ_WIN32) && PJ_WIN32!=0
	    if (freopen ("CONIN$", "r", stdin) == NULL) {
#else
	    if (1) {
#endif
		puts("Cannot switch back to console from file redirection");
		menuin[0] = 'q';
		menuin[1] = '\0';
	    } else {
		puts("Switched back to console from file redirection");
		continue;
	    }
	}

	switch (menuin[0]) {

	case 'm':
	    /* Make call! : */
	    printf("(You currently have %d calls)\n", 
		     pjsua_call_get_count());
	    
	    uri = NULL;
	    ui_input_url("Make call", buf, sizeof(buf), &result);
	    if (result.nb_result != NO_NB) {

		if (result.nb_result == -1 || result.nb_result == 0) {
		    puts("You can't do that with make call!");
		    continue;
		} else {
		    pjsua_buddy_info binfo;
		    pjsua_buddy_get_info(result.nb_result-1, &binfo);
		    uri = binfo.uri.ptr;
		}

	    } else if (result.uri_result) {
		uri = result.uri_result;
	    }
	    
	    tmp = pj_str(uri);
	    pjsua_call_make_call( current_acc, &tmp, 0, NULL, NULL, NULL);
	    break;

	case 'M':
	    /* Make multiple calls! : */
	    printf("(You currently have %d calls)\n", 
		   pjsua_call_get_count());
	    
	    if (!simple_input("Number of calls", menuin, sizeof(menuin)))
		continue;

	    count = my_atoi(menuin);
	    if (count < 1)
		continue;

	    ui_input_url("Make call", buf, sizeof(buf), &result);
	    if (result.nb_result != NO_NB) {
		pjsua_buddy_info binfo;
		if (result.nb_result == -1 || result.nb_result == 0) {
		    puts("You can't do that with make call!");
		    continue;
		}
		pjsua_buddy_get_info(result.nb_result-1, &binfo);
		uri = binfo.uri.ptr;
	    } else {
		uri =  result.uri_result;
	    }

	    for (i=0; i<my_atoi(menuin); ++i) {
		pj_status_t status;
	    
		tmp = pj_str(uri);
		status = pjsua_call_make_call(current_acc, &tmp, 0, NULL,
					      NULL, NULL);
		if (status != PJ_SUCCESS)
		    break;
	    }
	    break;

	case 'i':
	    /* Send instant messaeg */

	    /* i is for call index to send message, if any */
	    i = -1;
    
	    /* Make compiler happy. */
	    uri = NULL;

	    /* Input destination. */
	    ui_input_url("Send IM to", buf, sizeof(buf), &result);
	    if (result.nb_result != NO_NB) {

		if (result.nb_result == -1) {
		    puts("You can't send broadcast IM like that!");
		    continue;

		} else if (result.nb_result == 0) {
    
		    i = current_call;

		} else {
		    pjsua_buddy_info binfo;
		    pjsua_buddy_get_info(result.nb_result-1, &binfo);
		    uri = binfo.uri.ptr;
		}

	    } else if (result.uri_result) {
		uri = result.uri_result;
	    }
	    

	    /* Send typing indication. */
	    if (i != -1)
		pjsua_call_send_typing_ind(i, PJ_TRUE, NULL);
	    else {
		pj_str_t tmp_uri = pj_str(uri);
		pjsua_im_typing(current_acc, &tmp_uri, PJ_TRUE, NULL);
	    }

	    /* Input the IM . */
	    if (!simple_input("Message", text, sizeof(text))) {
		/*
		 * Cancelled.
		 * Send typing notification too, saying we're not typing.
		 */
		if (i != -1)
		    pjsua_call_send_typing_ind(i, PJ_FALSE, NULL);
		else {
		    pj_str_t tmp_uri = pj_str(uri);
		    pjsua_im_typing(current_acc, &tmp_uri, PJ_FALSE, NULL);
		}
		continue;
	    }

	    tmp = pj_str(text);

	    /* Send the IM */
	    if (i != -1)
		pjsua_call_send_im(i, NULL, &tmp, NULL, NULL);
	    else {
		pj_str_t tmp_uri = pj_str(uri);
		pjsua_im_send(current_acc, &tmp_uri, NULL, &tmp, NULL, NULL);
	    }

	    break;

	case 'a':

	    if (current_call != -1) {
		pjsua_call_get_info(current_call, &call_info);
	    } else {
		/* Make compiler happy */
		call_info.role = PJSIP_ROLE_UAC;
		call_info.state = PJSIP_INV_STATE_DISCONNECTED;
	    }

	    if (current_call == -1 || 
		call_info.role != PJSIP_ROLE_UAS ||
		call_info.state >= PJSIP_INV_STATE_CONNECTING)
	    {
		puts("No pending incoming call");
		fflush(stdout);
		continue;

	    } else {
		int st_code;
		char contact[120];
		pj_str_t hname = { "Contact", 7 };
		pj_str_t hvalue;
		pjsip_generic_string_hdr hcontact;
		pjsua_msg_data msg_data;

		if (!simple_input("Answer with code (100-699)", buf, sizeof(buf)))
		    continue;
		
		st_code = my_atoi(buf);
		if (st_code < 100)
		    continue;

		pjsua_msg_data_init(&msg_data);

		if (st_code/100 == 3) {
		    if (!simple_input("Enter URL to be put in Contact", 
				      contact, sizeof(contact)))
			continue;
		    hvalue = pj_str(contact);
		    pjsip_generic_string_hdr_init2(&hcontact, &hname, &hvalue);

		    pj_list_push_back(&msg_data.hdr_list, &hcontact);
		}

		/*
		 * Must check again!
		 * Call may have been disconnected while we're waiting for 
		 * keyboard input.
		 */
		if (current_call == -1) {
		    puts("Call has been disconnected");
		    fflush(stdout);
		    continue;
		}

		pjsua_call_answer(current_call, st_code, NULL, &msg_data);
	    }

	    break;


	case 'h':

	    if (current_call == -1) {
		puts("No current call");
		fflush(stdout);
		continue;

	    } else if (menuin[1] == 'a') {
		
		/* Hangup all calls */
		pjsua_call_hangup_all();

	    } else {

		/* Hangup current calls */
		pjsua_call_hangup(current_call, 0, NULL, NULL);
	    }
	    break;

	case ']':
	case '[':
	    /*
	     * Cycle next/prev dialog.
	     */
	    if (menuin[0] == ']') {
		find_next_call();

	    } else {
		find_prev_call();
	    }

	    if (current_call != -1) {
		
		pjsua_call_get_info(current_call, &call_info);
		PJ_LOG(3,(THIS_FILE,"Current dialog: %.*s", 
			  (int)call_info.remote_info.slen, 
			  call_info.remote_info.ptr));

	    } else {
		PJ_LOG(3,(THIS_FILE,"No current dialog"));
	    }
	    break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -