📄 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 -2struct 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; case '>': case '<': if (!simple_input("Enter account ID to select", buf, sizeof(buf))) break; i = my_atoi(buf); if (pjsua_acc_is_valid(i)) { pjsua_acc_set_default(i); PJ_LOG(3,(THIS_FILE, "Current account changed to %d", i)); } else { PJ_LOG(3,(THIS_FILE, "Invalid account id %d", i));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -