//---------------------------------------------------------------------- bool SipPhone::removeCallFromConference(const int &call_src, const int &call_dest) { int src = call_src; int dest = call_dest; if (src == -1 || dest == -1) { LogInfo info(LogInfo::STATUS_ERROR, "pjsip", 0, "Error: one of the selected calls does NOT exist!"); signalLogData(info); return false; } pjsua_call_info src_ci, dest_ci; pjsua_call_get_info(src,&src_ci); pjsua_call_get_info(dest,&dest_ci); pj_status_t status = pjsua_conf_disconnect(src_ci.conf_slot,dest_ci.conf_slot); if (status != PJ_SUCCESS) { LogInfo info(LogInfo::STATUS_ERROR, "pjsip", status, "Error connecting conference (1/2)!"); signalLogData(info); return false; } return true; }
/* Callback called by the library when call's state has changed */ static void on_call_state(pjsua_call_id call_id, pjsip_event *e) { pjsua_call_info ci; PJ_UNUSED_ARG(e); pjsua_call_get_info(call_id, &ci); PJ_LOG(3, (THIS_FILE, "Call %d state=%.*s", call_id, (int) ci.state_text.slen, ci.state_text.ptr)); pjsua_call_get_info(call_id, &ci); char buf[ci.remote_info.slen]; memcpy(&buf, ci.remote_info.ptr, ci.remote_info.slen); or_event_call_state (call_id, ci.state); if (ci.state == PJSIP_INV_STATE_CALLING) { or_event_outgoing_call(buf, call_id, ci.state); } else if (ci.state == PJSIP_INV_STATE_DISCONNECTED) { //TODO: or_event (OR_HANGUP, "Either you or the other party hung up."); } }
void ScreenPhone::showVideoWindow(pjsua_call_id call_id) { pjsua_call_info cinfo; unsigned i; if (call_id == -1) return; pjsua_call_get_info(call_id, &cinfo); qDebug() << "Opening video window......."; for (i = 0; i < cinfo.media_cnt; ++i) { if ((cinfo.media[i].type == PJMEDIA_TYPE_VIDEO) && (cinfo.media[i].dir & PJMEDIA_DIR_DECODING)) { pjsua_vid_win_info wi; pjsua_vid_win_get_info(cinfo.media[i].stream.vid.win_in, &wi); const pjmedia_rect_size size = {320, 240}; const pjmedia_coord pos = {(controller->qmlviewer->x()+controller->qmlviewer->width()),controller->qmlviewer->y()+210}; pjsua_vid_win_set_size(cinfo.media[i].stream.vid.win_in, &size); pjsua_vid_win_set_pos(cinfo.media[i].stream.vid.win_in, &pos); this->controller->screenSettings->showPreviewWindow(controller->settings->m_videoDevice.m_name.append("::::").append(controller->settings->m_videoDevice.m_id)); this->m_video_viewer = new VidWin(&wi.hwnd); break; } } }
struct my_call_data *call_init_tonegen(pjsua_call_id call_id) { pj_pool_t *pool; struct my_call_data *cd; pjsua_call_info ci; if (call_id !=-1 ) { pjsua_call_get_info(call_id, &ci); } pool = pjsua_pool_create("mycall", 512, 512); cd = PJ_POOL_ZALLOC_T(pool, struct my_call_data); cd->pool = pool; pjmedia_tonegen_create(cd->pool, 8000, 1, 160, 16, 0, &cd->tonegen); pjsua_conf_add_port(cd->pool, cd->tonegen, &cd->toneslot); if (call_id !=-1 ) { pjsua_conf_connect(cd->toneslot, ci.conf_slot); } pjsua_conf_connect(cd->toneslot, 0); if(call_id !=-1) { pjsua_call_set_user_data(call_id, (void*) cd); } return cd; }
void ScreenPhone::sendDTMF(pjsua_call_id call_id, const char* digits) { const char* p_digits; p_digits = digits; pj_str_t pj_digits = pj_str((char*)p_digits); pjsua_call_info call_info; //qDebug() << "Trying to play dtmf " << digits; if(call_id>=0) { pjsua_call_get_info(call_id, &call_info); if (call_info.media_status == PJSUA_CALL_MEDIA_ACTIVE) { playDTMF(call_id, (char*)p_digits); pjsua_call_dial_dtmf(call_id, &pj_digits); return; } } else { playDTMF(call_id, (char*)p_digits); } }
static void on_call_media_state(pjsua_call_id call_id) { #if PJMEDIA_HAS_VIDEO pjsua_call_info call_info; unsigned mi; pjsua_call_get_info(call_id, &call_info); for (mi=0; mi<call_info.media_cnt; ++mi) { pjsua_call_media_info *med_info = &call_info.media[mi]; if (med_info->type == PJMEDIA_TYPE_VIDEO && med_info->status == PJSUA_CALL_MEDIA_ACTIVE && med_info->stream.vid.win_in != PJSUA_INVALID_ID) { pjmedia_vid_dev_hwnd vhwnd; /* Setup renderer surface */ pj_bzero(&vhwnd, sizeof(vhwnd)); vhwnd.type = PJMEDIA_VID_DEV_HWND_TYPE_ANDROID; vhwnd.info.window = callVideoSurface; pjsua_vid_win_set_win(med_info->stream.vid.win_in, &vhwnd); break; } } #endif /* Forward to original callback */ if (pjsua_cb_orig.on_call_media_state) (*pjsua_cb_orig.on_call_media_state)(call_id); }
void SipAccount::onCallState(pjsua_call_id call_id, pjsip_event* e) { Logger::debug("SipAccount::onCallState(call_id=%d)...", call_id); PJ_UNUSED_ARG(e); pjsua_call_info ci; pjsua_call_get_info(call_id, &ci); 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 state = std::string(pj_strbuf(&ci.state_text), ci.state_text.slen); Logger::debug("[%s] call state changed to %s", number.c_str(), state.c_str()); #if 1 if (ci.state == PJSIP_INV_STATE_CONFIRMED) { Logger::debug("hangup..."); // code 0: pj takes care of hangup SIP status code pj_status_t status = pjsua_call_hangup(call_id, 0, NULL, NULL); if (status != PJ_SUCCESS) { Logger::warn("pjsua_call_hangup() failed (%s)", Helper::getPjStatusAsString(status).c_str()); } } #endif }
void BlabbleCall::OnCallState(pjsua_call_id call_id, pjsip_event *e) { pjsua_call_info info; if (pjsua_call_get_info(call_id, &info) == PJ_SUCCESS) { if (info.state == PJSIP_INV_STATE_DISCONNECTED) { RemoteEnd(info); } else if (info.state == PJSIP_INV_STATE_CALLING) { if (on_call_ringing_) on_call_ringing_->InvokeAsync("", FB::variant_list_of(BlabbleCallWeakPtr(get_shared()))); BlabbleAccountPtr p = parent_.lock(); if (p) p->OnCallRingChange(get_shared(), info); } else if (info.state == PJSIP_INV_STATE_CONFIRMED) { if (on_call_connected_) on_call_connected_->InvokeAsync("", FB::variant_list_of(BlabbleCallWeakPtr(get_shared()))); BlabbleAccountPtr p = parent_.lock(); if (p) p->OnCallRingChange(get_shared(), info); } } }
void MainWin::on_call_state(pjsua_call_id call_id, pjsip_event *e) { pjsua_call_info ci; PJ_UNUSED_ARG(e); pjsua_call_get_info(call_id, &ci); if (currentCall_ == -1 && ci.state < PJSIP_INV_STATE_DISCONNECTED && ci.role == PJSIP_ROLE_UAC) { emit signalNewCall(call_id, false); } char status[80]; if (ci.state == PJSIP_INV_STATE_DISCONNECTED) { snprintf(status, sizeof(status), "Call is %s (%s)", ci.state_text.ptr, ci.last_status_text.ptr); showStatus(status); emit signalCallReleased(); } else { snprintf(status, sizeof(status), "Call is %s", pjsip_inv_state_name(ci.state)); showStatus(status); } }
/* Called by the library when a transaction within the call has changed state. */ static void on_call_tsx_state (pjsua_call_id call_id, pjsip_transaction *tsx, pjsip_event *e) { PJ_UNUSED_ARG(e); pjsua_call_info ci; pjsua_call_get_info(call_id, &ci); if (tsx == NULL) { or_event_call_tsx_state (call_id, -1); } else { or_event_call_tsx_state (call_id, tsx->status_code); if ((tsx->status_code == 180) && (previous_invitation_state == PJSIP_INV_STATE_CALLING)) { //TODO: or_event (OR_RINGING, "Maybe somebody will pick up the phone at the other end soon."); } else if ((tsx->status_code == 200) && (ci.state == PJSIP_INV_STATE_CONFIRMED)) { //TODO: or_event (OR_CONNECTED, "Somebody picked up the phone at the other end."); } } previous_invitation_state = ci.state; }
// REITEK: Callback to handle transaction state changes //Static void PjsuaManager::OnCallTsxState(pjsua_call_id call_id, pjsip_transaction *tsx, pjsip_event *e) { PjsuaManagerPtr manager = PjsuaManager::instance_.lock(); if (!manager) return; pjsua_call_info info; pj_status_t status; if ((status = pjsua_call_get_info(call_id, &info)) == PJ_SUCCESS) { std::string str = "PjsuaManager::OnCallTsxState called with PJSIP call id: " + boost::lexical_cast<std::string>(call_id)+", state: " + boost::lexical_cast<std::string>(info.state); BlabbleLogging::blabbleLog(0, str.c_str(), 0); //BLABBLE_LOG_TRACE("PjsuaManager::OnCallTsxState called with PJSIP call id: "<< call_id << ", state: " << info.state); BlabbleAccountPtr acc = manager->FindAcc(info.acc_id); if (acc) { acc->OnCallTsxState(call_id, tsx, e); } // REITEK: !!! CHECK: If this necessary/wanted? if (info.state == PJSIP_INV_STATE_DISCONNECTED) { //Just make sure we get rid of the call pjsua_call_hangup(call_id, 0, NULL, NULL); } } else { std::string str = "PjsuaManager::OnCallTsxState failed to call pjsua_call_get_info for PJSIP call id: " + boost::lexical_cast<std::string>(call_id)+", got status: " + boost::lexical_cast<std::string>(status); BlabbleLogging::blabbleLog(0, str.c_str(), 0); //BLABBLE_LOG_ERROR("PjsuaManager::OnCallTsxState failed to call pjsua_call_get_info for PJSIP call id: "<< call_id << ", got status: " << status); } }
/* * Handler when invite state has changed. */ static void on_call_state (pjsua_call_id call_id, pjsip_event *e) { pjsua_call_info call_info; PJ_UNUSED_ARG (e); pjsua_call_get_info (call_id, &call_info); if (call_info.state == PJSIP_INV_STATE_DISCONNECTED) { g_current_call = PJSUA_INVALID_ID; SetURI (SIP_DST_URI, -1); SetAction (ID_MENU_CALL); //SetCallStatus(call_info.state_text.ptr, call_info.state_text.slen); SetCallStatus (call_info.last_status_text.ptr, call_info.last_status_text.slen); } else { //if (g_current_call == PJSUA_INVALID_ID) // g_current_call = call_id; if (call_info.remote_contact.slen) SetURI (call_info.remote_contact.ptr, call_info.remote_contact.slen, false); else SetURI (call_info.remote_info.ptr, call_info.remote_info.slen, false); if (call_info.state == PJSIP_INV_STATE_CONFIRMED) SetAction (ID_MENU_DISCONNECT); SetCallStatus (call_info.state_text.ptr, call_info.state_text.slen); } }
/* Callback called by the library upon receiving incoming call */ static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id, pjsip_rx_data *rdata) { pjsua_call_info ci; PJ_UNUSED_ARG(acc_id); PJ_UNUSED_ARG(rdata); pjsua_call_get_info(call_id, &ci); char buf[ci.remote_info.slen]; memcpy(&buf, ci.remote_info.ptr, ci.remote_info.slen); or_event_incoming_call (buf, call_id, ci.state); current_call = call_id; PJ_LOG(3, (THIS_FILE, "Incoming call from %.*s!!", (int) ci.remote_info.slen, ci.remote_info.ptr)); if (autoanswer[0]) { pjsua_call_answer(call_id, 200, NULL, NULL); } else { pjsua_call_answer(call_id, 180, NULL, NULL); //Acknowledge the call. } }
// ZRTP and other media dispatcher pjmedia_transport* on_transport_created_wrapper(pjsua_call_id call_id, unsigned media_idx, pjmedia_transport *base_tp, unsigned flags) { pj_status_t status = PJ_SUCCESS; pjsua_call_info call_info; void* acc_user_data; int acc_use_zrtp = -1; // By default, use default global def pj_bool_t use_zrtp = css_var.default_use_zrtp; status = pjsua_call_get_info(call_id, &call_info); if(status == PJ_SUCCESS && pjsua_acc_is_valid (call_info.acc_id)){ acc_user_data = pjsua_acc_get_user_data(call_info.acc_id); if(acc_user_data != NULL){ acc_use_zrtp = ((csipsimple_acc_config *) acc_user_data)->use_zrtp; if(acc_use_zrtp >= 0){ use_zrtp = (acc_use_zrtp == 1) ? PJ_TRUE : PJ_FALSE; } } } #if defined(PJMEDIA_HAS_ZRTP) && PJMEDIA_HAS_ZRTP!=0 if(use_zrtp){ PJ_LOG(4, (THIS_FILE, "Dispatch transport creation on ZRTP one")); return on_zrtp_transport_created(call_id, media_idx, base_tp, flags); } #endif return base_tp; }
//Ended by us void BlabbleCall::LocalEnd() { pjsua_call_id old_id = INTERLOCKED_EXCHANGE((volatile long *)&call_id_, (long)INVALID_CALL); if (old_id == INVALID_CALL || old_id < 0 || old_id >= (long)pjsua_call_get_max_count()) { return; } StopRinging(); pjsua_call_info info; if (pjsua_call_get_info(old_id, &info) == PJ_SUCCESS && info.conf_slot > 0) { //Kill the audio pjsua_conf_disconnect(info.conf_slot, 0); pjsua_conf_disconnect(0, info.conf_slot); } pjsua_call_hangup(old_id, 0, NULL, NULL); if (on_call_end_) { BlabbleCallPtr call = get_shared(); on_call_end_->getHost()->ScheduleOnMainThread(call, boost::bind(&BlabbleCall::CallOnCallEnd, call)); } BlabbleAccountPtr p = parent_.lock(); if (p) p->OnCallEnd(get_shared()); }
void MainWin::initVideoWindow() { pjsua_call_info ci; unsigned i; if (currentCall_ == -1) return; delete video_; video_ = NULL; pjsua_call_get_info(currentCall_, &ci); for (i = 0; i < ci.media_cnt; ++i) { if ((ci.media[i].type == PJMEDIA_TYPE_VIDEO) && (ci.media[i].dir & PJMEDIA_DIR_DECODING)) { pjsua_vid_win_info wi; pjsua_vid_win_get_info(ci.media[i].stream.vid.win_in, &wi); video_= new VidWin(&wi.hwnd); video_->putIntoLayout(vbox_left); break; } } }
static void on_call_state (pjsua_call_id call_id, pjsip_event *e) { ics_t *data; pjsua_call_info ci; PJ_UNUSED_ARG(e); pjsua_call_get_info(call_id, &ci); //Handle hold call problem #if 0 if ( (strcmp(ci.state_text.ptr,"CALLING") == 0) && (current_call != PJSUA_INVALID_ID) ) _ics_core_hold_call(data); #endif current_call = call_id; if (strcmp(ci.state_text.ptr,"DISCONNCTD") == 0){ find_call(); } data = (ics_t *)pjsua_acc_get_user_data(ci.acc_id); opool_item_t *p_item = opool_get(&data->opool); build_call_state_event((ics_event_t *)p_item->data, call_id, ci.state_text.ptr); ics_event_t *event = (ics_event_t *)p_item->data; process_event(event); }
// handler for call-state-change-events static void on_call_state(pjsua_call_id call_id, pjsip_event *e) { // get call infos pjsua_call_info ci; pjsua_call_get_info(call_id, &ci); // prevent warning about unused argument e PJ_UNUSED_ARG(e); // check call state if (ci.state == PJSIP_INV_STATE_CONFIRMED) { log_message("Call confirmed.\n"); call_confirmed = 1; // ensure that message is played from start if (play_id != PJSUA_INVALID_ID) { pjmedia_wav_player_port_set_pos(play_port, 0); } } if (ci.state == PJSIP_INV_STATE_DISCONNECTED) { log_message("Call disconnected.\n"); // exit app if call is finished/disconnected app_exit(); } }
/** * \fn _ics_core_transfer_call() * \brief Chuyen huong cuoc goi * \param agr1: ics_t *data * agr2: int call_id_1 * agr3: int call_id_2 */ static void _ics_core_transfer_call(ics_t *data, int call_id_1, int call_id_2) { #if 0 if ( (call_id_1 != call_id_2) && pjsua_call_is_active(call_id_1) && pjsua_call_is_active(call_id_2) ) { pjsua_call_xfer_replaces(call_id_1, call_id_2, 0, NULL); } else printf("Cannot transfer call!\n"); #endif //For test only: #if 1 int i, max; pjsua_call_info ci; max = pjsua_call_get_count(); printf("You have %d active call%s\n", max, (max>1?"s":"")); for (i = 0; i < max; i++){ if (pjsua_call_is_active(i)) { pjsua_call_get_info(i, &ci); pjsua_call_xfer_replaces(current_call, ci.id, 0, NULL); break; } } #endif }
void call_hangup_fast(pjsua_call_id call_id,pjsua_call_info *p_call_info) { pjsua_call_info call_info; if (!p_call_info) { if (pjsua_call_get_info(call_id, &call_info) == PJ_SUCCESS) { p_call_info = &call_info; } } if (p_call_info) { if (p_call_info->state==PJSIP_INV_STATE_CALLING || (p_call_info->role==PJSIP_ROLE_UAS && p_call_info->state==PJSIP_INV_STATE_CONNECTING) ) { pjsua_call *call = &pjsua_var.calls[call_id]; pjsip_tx_data *tdata = NULL; // Generate an INVITE END message if (pjsip_inv_end_session(call->inv, 487, NULL, &tdata) != PJ_SUCCESS || !tdata) { pjsip_inv_terminate(call->inv,487,PJ_TRUE); } else { // Send that END request if (pjsip_endpt_send_request(pjsua_get_pjsip_endpt(), tdata, -1, NULL, NULL) != PJ_SUCCESS) { pjsip_inv_terminate(call->inv,487,PJ_TRUE); } } return; } } pjsua_call_hangup(call_id, 0, NULL, NULL); }
struct my_call_data *call_init_tonegen(pjsua_call_id call_id) { pj_pool_t *pool; struct my_call_data *cd; pjsua_call_info ci; if (call_id !=-1 ) { pjsua_call_get_info(call_id, &ci); if (ci.media_status != PJSUA_CALL_MEDIA_ACTIVE) return NULL; } pool = pjsua_pool_create("mycall", 512, 512); cd = PJ_POOL_ZALLOC_T(pool, struct my_call_data); cd->pool = pool; pjmedia_tonegen_create(cd->pool, 8000, 1, 160, 16, 0, &cd->tonegen); pjsua_conf_add_port(cd->pool, cd->tonegen, &cd->toneslot); if (call_id !=-1 ) { pjsua_conf_connect(cd->toneslot, ci.conf_slot); } if (accountSettings.localDTMF) { pjsua_conf_connect(cd->toneslot, 0); } if (call_id !=-1 ) { pjsua_call_set_user_data(call_id, (void*) cd); } return cd; }
//Static void PjsuaManager::OnCallMediaState(pjsua_call_id call_id) { PjsuaManagerPtr manager = PjsuaManager::instance_.lock(); if (!manager) return; pjsua_call_info info; pj_status_t status; if ((status = pjsua_call_get_info(call_id, &info)) == PJ_SUCCESS) { std::string str = "PjsuaManager::OnCallMediaState called with PJSIP call id: " + boost::lexical_cast<std::string>(call_id)+", state: " + boost::lexical_cast<std::string>(info.state); BlabbleLogging::blabbleLog(0, str.c_str(), 0); //BLABBLE_LOG_TRACE("PjsuaManager::OnCallMediaState called with PJSIP call id: " << call_id << ", state: " << info.state); BlabbleAccountPtr acc = manager->FindAcc(info.acc_id); if (acc) { acc->OnCallMediaState(call_id); } } else { std::string str = "PjsuaManager::OnCallMediaState failed to call pjsua_call_get_info for PJSIP call id: " + boost::lexical_cast<std::string>(call_id)+", got status: " + boost::lexical_cast<std::string>(status); BlabbleLogging::blabbleLog(0, str.c_str(), 0); //BLABBLE_LOG_ERROR("PjsuaManager::OnCallMediaState failed to call pjsua_call_get_info for PJSIP call id: " << call_id << ", got status: " << status); } }
// helper for creating call-media-player static void create_player(pjsua_call_id call_id) { // get call infos pjsua_call_info ci; pjsua_call_get_info(call_id, &ci); pj_str_t name; pj_status_t status = PJ_ENOTFOUND; log_message("Creating player ... "); // create player for playback media if (app_cfg.wav_file) { status = pjsua_player_create(pj_cstr(&name, app_cfg.wav_file), 0, &play_id); } else { status = pjsua_player_create(pj_cstr(&name, app_cfg.tts_file), 0, &play_id); } if (status != PJ_SUCCESS) error_exit("Error playing sound-playback", status); // connect active call to media player pjsua_conf_connect(pjsua_player_get_conf_port(play_id), ci.conf_slot); // get media port (play_port) from play_id status = pjsua_player_get_port(play_id, &play_port); if (status != PJ_SUCCESS) error_exit("Error getting sound player port", status); // register media finished callback status = pjmedia_wav_player_set_eof_cb(play_port, NULL, &on_media_finished); if (status != PJ_SUCCESS) error_exit("Error adding sound-playback callback", status); log_message("Done.\n"); }
//---------------------------------------------------------------------- void SipPhone::muteMicrophoneForCall(const int &call_id, const float &mute) { pjsua_call_info ci; pjsua_call_get_info(call_id,&ci); pjsua_conf_adjust_tx_level(ci.conf_slot, mute); }
/* Callback called by PJSUA when call's state has changed */ static void on_call_state(pjsua_call_id call_id, pjsip_event *e) { if (!doorcom) { return; } pjsua_call_info ci; pjsua_call_get_info(call_id, &ci); doorcom->onCallState_wrapper(call_id,QVDoorcom::pj2qstring(ci.state_text)); }
/* Callback called by the library when call's state has changed */ static void on_call_state(pjsua_call_id call_id, pjsip_event *e) { pjsua_call_info ci; PJ_UNUSED_ARG(e); pjsua_call_get_info(call_id, &ci); // PJ_LOG(3, (THIS_FILE, "Call %d state=%.*s", call_id, // (int)ci.state_text.slen, ci.state_text.ptr)); }
/* Callback called by PJSUA when call's media state has changed */ static void on_call_media_state(pjsua_call_id call_id) { qDebug() << "Call media state"; pjsua_call_info ci; if (pjsua_call_get_info(call_id, &ci) != PJ_SUCCESS) { return; } pjsua_conf_connect(ci.conf_slot, 0); pjsua_conf_connect(0, ci.conf_slot); }
void RinginDlg::OnBnClickedDecline() { pjsua_call_info call_info; pjsua_call_get_info(call_id,&call_info); if (pjsua_call_hangup(call_id, 0, NULL, NULL) == PJ_SUCCESS) { microsipDlg->callIdImcomingIgnore = PjToStr(&call_info.call_id); } Close(); }
void on_call_state(pjsua_call_id call_id, pjsip_event *e) { pjsua_call_info call_info; printf("on_call_status\n"); pjsua_call_get_info(call_id, &call_info); if (call_info.state == PJSIP_INV_STATE_DISCONNECTED) { printf("PJSIP_INV_STATE_DISCONNECTED\n"); } }
void QVDoorcom::onHangupPressed() { popup->hide(); if (active_call < 0) { return; } pjsua_call_info ci; if (!pjsua_call_get_info(active_call, &ci) == PJ_SUCCESS) { return; } pjsua_conf_disconnect(bell_port_id,0); qDebug() << pj2qstring( ci.state_text); if ((ci.state == PJSIP_INV_STATE_INCOMING) || (ci.state == PJSIP_INV_STATE_EARLY)) { pjsua_call_answer(active_call,486,NULL,NULL); /* Reject with busy */ active_call = -1; } else if (ci.state == PJSIP_INV_STATE_CONNECTING) { pjsua_call_hangup(active_call,200,NULL,NULL); /* Hangup */ active_call = -1; } else { if (!code_hangup.isEmpty()) { #ifdef USE_INBAND pjmedia_tone_digit d[16]; unsigned i, count = code_hangup.length(); if (count > PJ_ARRAY_SIZE(d)) { count = PJ_ARRAY_SIZE(d); } pj_bzero(d, sizeof(d)); int n=0; for (i=0; i<count; i++) { char code = code_hangup.at(i).toLatin1(); qDebug() << "i" << i << code << "n" << n; if (((code < '0') || (code > '9')) && (code != '*') && (code != '#')) { continue; } d[n].digit = code; d[n].on_msec = 200; d[n].off_msec = 200; d[n].volume = 0; n++; } pjmedia_tonegen_play_digits(pj_tonegen, n, d, 0); #else pj_str_t code = pj_str(strdup(code_hangup.toUtf8().data())); pjsua_call_dial_dtmf(active_call,&code); #endif hangup_timer.setInterval(400*code_hangup.length()); } else { hangup_timer.setInterval(100); } qDebug() << "hangup timer started"; hangup_timer.start(); } }