void MainWin::on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id, pjsip_rx_data *rdata) { PJ_UNUSED_ARG(acc_id); PJ_UNUSED_ARG(rdata); if (currentCall_ != -1) { pjsua_call_answer(call_id, PJSIP_SC_BUSY_HERE, NULL, NULL); return; } emit signalNewCall(call_id, true); pjsua_call_info ci; char status[80]; pjsua_call_get_info(call_id, &ci); snprintf(status, sizeof(status), "Incoming call from %.*s", (int)ci.remote_info.slen, ci.remote_info.ptr); showStatus(status); }
void QPhoneHandler::onAccept() { pjsua_call_answer(callId, PJSIP_SC_OK, nullptr, nullptr); }
void QPhoneHandler::onCancel() { pjsua_call_answer(callId, PJSIP_SC_TEMPORARILY_UNAVAILABLE, nullptr, nullptr); }
static LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; switch (message) { case WM_KEYUP: if (wParam==114) { wParam = ID_MENU_CALL; } else if (wParam==115) { if (g_current_call == PJSUA_INVALID_ID) wParam = ID_EXIT; else wParam = ID_MENU_DISCONNECT; } else break; case WM_COMMAND: wmId = LOWORD (wParam); wmEvent = HIWORD (wParam); if (wmId == ID_BTN_ACTION) wmId = g_current_action; switch (wmId) { case ID_MENU_CALL: if (g_current_call != PJSUA_INVALID_ID) { MessageBox (NULL, TEXT ("Can not make call"), TEXT ("You already have one call active"), MB_OK); } pj_str_t dst_uri; wchar_t text[256]; char tmp[256]; pj_status_t status; GetWindowText (hwndURI, text, PJ_ARRAY_SIZE (text)); pj_unicode_to_ansi (text, pj_unicode_strlen (text), tmp, sizeof (tmp)); dst_uri.ptr = tmp; dst_uri.slen = pj_ansi_strlen (tmp); status = pjsua_call_make_call (g_current_acc, &dst_uri, 0, NULL, NULL, &g_current_call); if (status != PJ_SUCCESS) OnError (TEXT ("Unable to make call"), status); break; case ID_MENU_ANSWER: if (g_current_call == PJSUA_INVALID_ID) MessageBox (NULL, TEXT ("Can not answer"), TEXT ("There is no call!"), MB_OK); else pjsua_call_answer (g_current_call, 200, NULL, NULL); break; case ID_MENU_DISCONNECT: if (g_current_call == PJSUA_INVALID_ID) MessageBox (NULL, TEXT ("Can not disconnect"), TEXT ("There is no call!"), MB_OK); else pjsua_call_hangup (g_current_call, PJSIP_SC_DECLINE, NULL, NULL); break; case ID_EXIT: DestroyWindow (hWnd); break; default: return DefWindowProc (hWnd, message, wParam, lParam); } break; case WM_CREATE: OnCreate (hWnd); break; case WM_DESTROY: OnDestroy(); CommandBar_Destroy (hwndCB); PostQuitMessage (0); break; case WM_TIMER: pjsua_handle_events (1); break; default: return DefWindowProc (hWnd, message, wParam, lParam); } return 0; }
/* * main() * * argv[] contains the registration information. */ int main(int argc, char *argv[]) { pj_status_t status; int loglevel = 0; if (argc < 4) { usage(argv[0]); exit(1); } if (argc > 5){ sscanf(argv[5], "%d", &loglevel); } pjsua_acc_id acc_id; /* Create pjsua first! */ status = pjsua_create(); if (status != PJ_SUCCESS) error_exit("Error in pjsua_create()", status); /* Init pjsua */ { pjsua_config cfg; pjsua_logging_config log_cfg; pjsua_media_config media_cfg; // This will prevent the SIP stack from trying to switch to TCP. // It will prevent the stack from giving "Transport unavailable" errors. // http://trac.pjsip.org/repos/wiki/Using_SIP_TCP pjsip_cfg()->endpt.disable_tcp_switch = PJ_TRUE; pjsua_config_default(&cfg); cfg.cb.on_incoming_call = &on_incoming_call; cfg.cb.on_call_media_state = &on_call_media_state; cfg.cb.on_call_state = &on_call_state; cfg.cb.on_call_tsx_state = &on_call_tsx_state; pjsua_logging_config_default(&log_cfg); log_cfg.console_level = loglevel; // 0 = Mute console, 3 = somewhat useful, 4 = overly verbose. pjsua_media_config_default(&media_cfg); status = pjsua_init(&cfg, &log_cfg, &media_cfg); if (status != PJ_SUCCESS) error_exit("Error in pjsua_init()", status); } /* Add UDP transport. */ { pjsua_transport_config cfg; pjsua_transport_config_default(&cfg); sscanf(argv[4], "%d", &cfg.port); status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, NULL); if (status != PJ_SUCCESS) error_exit("Error creating transport", status); printf("Created UDP transport on port %d.\n", cfg.port); } /* Initialization is done, now start pjsua */ status = pjsua_start(); if (status != PJ_SUCCESS) error_exit("Error starting pjsua", status); /* Register to SIP server by creating SIP account. */ { char reg_uri_buf[80] = "sip:"; char uri_buf[80] = "sip:"; pjsua_acc_config cfg; char* username = argv[1]; char* password = argv[2]; char* domain = argv[3]; strcat (uri_buf, username); strcat (reg_uri_buf, domain); strcat (uri_buf, "@"); strcat (uri_buf, domain); pjsua_acc_config_default(&cfg); cfg.id = pj_str(uri_buf); printf("Registering: %.*s.\n", (int)cfg.id.slen, cfg.id.ptr); cfg.reg_uri = pj_str(reg_uri_buf); cfg.cred_count = 1; cfg.cred_info[0].realm = pj_str(domain); cfg.cred_info[0].scheme = pj_str("Digest"); cfg.cred_info[0].username = pj_str(username); cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD; cfg.cred_info[0].data = pj_str(password); cfg.register_on_acc_add = PJ_FALSE; status = pjsua_acc_add(&cfg, PJ_TRUE, &acc_id); if (status != PJ_SUCCESS) error_exit("Error adding account", status); or_event(OR_READY, "Agent initialized.."); } /* Start by muting the audio device. This a passive agent, and sound is just wasted CPU time and uwanted side effects. */ pjsua_set_null_snd_dev(); fflush(stdout); /* Wait until user press "q" to quit. */ for (;;) { char option[256]; if (fgets(option, sizeof (option), stdin) == NULL) { or_status (OR_ERROR, "EOF while reading stdin, will quit now.."); break; } /* Dial command. */ if (option[0] == 'd') { pj_str_t uri = pj_str(&option[1]); status = pjsua_call_make_call(acc_id, &uri, 0, NULL, NULL, NULL); if (status != PJ_SUCCESS) { or_status (OR_ERROR, "Could not make call"); } else { or_status (OR_OK, "Dialling..."); } } /* Register */ else if (option[0] == 'r') { register_account(acc_id); } /* Unregister */ else if (option[0] == 'u') { unregister_account(acc_id); } /* Enable autoanswer */ else if (option[0] == 'a') { if (option[1] == '1') { autoanswer[0] = true; or_status(OR_OK, "Autoanswer enabled."); } else { or_status(OR_ERROR, "Invalid account."); } } /* Disable autoanswer (manual answer) */ else if (option[0] == 'm') { autoanswer[0] = false; or_status(OR_OK, "Autoanswer disabled."); } /* Pickup incoming call, unsupported for now. */ else if (option[0] == 'p') { if (current_call != PJSUA_INVALID_ID) { pjsua_call_answer(current_call, 200, NULL, NULL); or_status(OR_OK, "Call picked up."); } else { or_status(OR_ERROR, "No call to pick up."); } } /* Hang up current call */ else if (option[0] == 'H') { if (current_call != PJSUA_INVALID_ID) { pjsua_call_hangup (current_call, 0,NULL, NULL); or_status (OR_OK, "Hanging up current call..."); } else { or_status(OR_ERROR, "No call to hang up."); } } /* Full hangup.. */ else if (option[0] == 'h') { pjsua_call_hangup_all(); or_status (OR_OK, "Hanging up all calls..."); } /* Status */ else if (option[0] == 's') { or_dump_status(); } /* Exit application. */ else if (option[0] == 'q') { break; } else { or_status (OR_ERROR, "Unknown command:"); } } pjsua_destroy(); or_status (OR_OK, "Exiting..."); return 0; }
void SipAccount::onIncomingCall(pjsua_call_id call_id, pjsip_rx_data *rdata) { Logger::debug("SipAccount::onIncomingCall(call_id=%d)...", call_id); PJ_UNUSED_ARG(rdata); pj_status_t status = pjsua_call_set_user_data(call_id, this); if (status != PJ_SUCCESS) { Logger::error("pjsua_acc_set_user_data() failed (%s)", Helper::getPjStatusAsString(status).c_str()); } pjsua_call_info ci; pjsua_call_get_info(call_id, &ci); #if 0 Logger::debug("local_info %s", pj_strbuf(&ci.local_info)); Logger::debug("local_contact %s", pj_strbuf(&ci.local_contact)); Logger::debug("remote_info %s", pj_strbuf(&ci.remote_info)); Logger::debug("remote_contact %s", pj_strbuf(&ci.remote_contact)); Logger::debug("call_id %s", pj_strbuf(&ci.call_id)); #endif std::string display, number; if (!getNumber(&ci.remote_info, &display, &number)) { Logger::warn("invalid URI received '%s'", pj_strbuf(&ci.remote_info)); return; } std::string msg; bool block = false; if (number == "anonymous" or number == "") { block = m_pPhone->isAnonymousNumberBlocked(&m_settings.base, &msg); } else { block = m_pPhone->isNumberBlocked(&m_settings.base, number, &msg); } Logger::notice(msg.c_str()); #if 0 // 302 redirect Use pjsua_call_hangup() and put the destination URL in the Contact header of the pjsua_msg_data. pj_pool_t* pool = pjsua_pool_create("", 512, 512); pjsua_msg_data msgData; pjsua_msg_data_init(&msgData); pj_str_t tmp; pjsip_generic_string_hdr* hdr = pjsip_generic_string_hdr_create(pool, pj_cstr(&tmp, "Contact"), pj_cstr(&tmp, "URI ...TODO")); pj_list_push_back(&msgData.hdr_list, hdr); // codes: http://de.wikipedia.org/wiki/SIP-Status-Codes // enum pjsip_status_code... pjsua_call_hangup(call_id, PJSIP_SC_MOVED_TEMPORARILY, NULL, &msgData); pj_pool_release(pool); #endif if (block) { // answer incoming calls with 200/OK, then we hangup in onCallState... pj_status_t status = pjsua_call_answer(call_id, 200, NULL, NULL); if (status != PJ_SUCCESS) { Logger::warn("pjsua_call_answer() failed (%s)", Helper::getPjStatusAsString(status).c_str()); } } }