📄 pjsua_app.c
字号:
}
/*
* 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 + -