예제 #1
0
//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());
}
예제 #2
0
//Ended by remote, could be becuase of an error
void BlabbleCall::RemoteEnd(const pjsua_call_info &info)
{
	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();

	//Kill the audio
	if (info.conf_slot > 0) 
	{
		pjsua_conf_disconnect(info.conf_slot, 0);
		pjsua_conf_disconnect(0, info.conf_slot);
	}

	pjsua_call_hangup(old_id, 0, NULL, NULL);

	if (info.last_status > 400)
	{
		std::string callerId;
		if (info.remote_contact.ptr == NULL)
		{
			callerId =std::string(info.remote_info.ptr, info.remote_info.slen);
		} 
		else
		{
			callerId = std::string(info.remote_contact.ptr, info.remote_contact.slen);
		}

		if (on_call_end_)
		{
			BlabbleCallPtr call = get_shared();
			on_call_end_->getHost()->ScheduleOnMainThread(call, boost::bind(&BlabbleCall::CallOnCallEnd, call, info.last_status));
		}
	} else {
		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());
}
예제 #3
0
//----------------------------------------------------------------------
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;
}
예제 #4
0
static void ui_conf_connect(char menuin[])
{
    char tmp[10], src_port[10], dst_port[10];
    pj_status_t status;
    int cnt;
    const char *src_title, *dst_title;

    cnt = sscanf(menuin, "%s %s %s", tmp, src_port, dst_port);

    if (cnt != 3) {
	ui_conf_list();

	src_title = (menuin[1]=='c'? "Connect src port #":
				     "Disconnect src port #");
	dst_title = (menuin[1]=='c'? "To dst port #":"From dst port #");

	if (!simple_input(src_title, src_port, sizeof(src_port)))
	    return;

	if (!simple_input(dst_title, dst_port, sizeof(dst_port)))
	    return;
    }

    if (menuin[1]=='c') {
	status = pjsua_conf_connect(my_atoi(src_port), my_atoi(dst_port));
    } else {
	status = pjsua_conf_disconnect(my_atoi(src_port), my_atoi(dst_port));
    }
    if (status == PJ_SUCCESS) {
	puts("Success");
    } else {
	puts("ERROR!!");
    }
}
예제 #5
0
파일: qvdoorcom.cpp 프로젝트: l0wside/qvisu
void QVDoorcom::onFilePlayed_wrapper() {
    pj_status_t status;

    status = pjsua_conf_disconnect(bell_port_id,0);
    if (status != PJ_SUCCESS) {
        qDebug() << "bell file played, disconnect:" << status;
    }
}
예제 #6
0
파일: qvdoorcom.cpp 프로젝트: l0wside/qvisu
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();
    }
}
예제 #7
0
void ring_stop(pjsua_call_id call_id) {
	if (css_var.ringback_on) {
		css_var.ringback_on = PJ_FALSE;

		pj_assert(css_var.ringback_cnt>0);
		if (--css_var.ringback_cnt == 0 &&
		css_var.ringback_slot!=PJSUA_INVALID_ID) {pjsua_conf_disconnect(css_var.ringback_slot, 0);
		pjmedia_tonegen_rewind(css_var.ringback_port);
	}
}
}
예제 #8
0
파일: qvdoorcom.cpp 프로젝트: l0wside/qvisu
void QVDoorcom::onAcceptPressed() {
    if (active_call < 0) {
        return;
    }

    pjsua_call_info ci;
    if (!pjsua_call_get_info(active_call, &ci) == PJ_SUCCESS) {
        return;
    }
    qDebug() << "Accepted, state is " << pj2qstring(ci.state_text);
    if ((ci.state != PJSIP_INV_STATE_INCOMING) && (ci.state != PJSIP_INV_STATE_EARLY)) {
        return;
    }

    pjsua_conf_disconnect(bell_port_id,0);

    pjsua_call_answer(active_call, 200, NULL, NULL);

}
예제 #9
0
static void systest_aec_test(void)
{
    const char *ref_wav_paths[] = { add_path(res_path, WAV_PLAYBACK_PATH),
				    ALT_PATH1 WAV_PLAYBACK_PATH };
    pjsua_player_id player_id = PJSUA_INVALID_ID;
    pjsua_recorder_id writer_id = PJSUA_INVALID_ID;
    enum gui_key key;
    test_item_t *ti;
    const char *title = "AEC/AES Test";
    unsigned last_ec_tail = 0;
    pj_status_t status;
    pj_str_t tmp;

    ti = systest_alloc_test_item(title);
    if (!ti)
	return;

    key = gui_msgbox(title,
		     "This test will try to find whether the AEC/AES "
		     "works good on this system. Test will play a file "
		     "while recording from mic. The recording will be "
		     "played back later so you can check if echo is there. "
		     "Press OK to start.",
		     WITH_OKCANCEL);
    if (key != KEY_OK) {
	ti->skipped = PJ_TRUE;
	return;
    }

    /* Save current EC tail */
    status = pjsua_get_ec_tail(&last_ec_tail);
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Set EC tail setting to default */
    status = pjsua_set_ec(PJSUA_DEFAULT_EC_TAIL_LEN, 0);
    if (status != PJ_SUCCESS)
	goto on_return;

    /*
     * Create player and recorder
     */
    status = create_player(PJ_ARRAY_SIZE(ref_wav_paths), ref_wav_paths,
			   &player_id);
    if (status != PJ_SUCCESS) {
	PJ_PERROR(1,(THIS_FILE, status, "Error opening WAV file %s",
		     WAV_PLAYBACK_PATH));
	goto on_return;
    }

    status = pjsua_recorder_create(
                 pj_cstr(&tmp, add_path(doc_path, AEC_REC_PATH)), 0, 0, -1,
                 0, &writer_id);
    if (status != PJ_SUCCESS) {
	PJ_PERROR(1,(THIS_FILE, status, "Error writing WAV file %s",
		     AEC_REC_PATH));
	goto on_return;
    }

    /*
     * Start playback and recording.
     */
    pjsua_conf_connect(pjsua_player_get_conf_port(player_id), 0);
    pj_thread_sleep(100);
    pjsua_conf_connect(0, pjsua_recorder_get_conf_port(writer_id));

    /* Wait user signal */
    gui_msgbox(title, "AEC/AES test is running. Press OK to stop this test.",
	       WITH_OK);

    /*
     * Stop and close playback and recorder
     */
    pjsua_conf_disconnect(0, pjsua_recorder_get_conf_port(writer_id));
    pjsua_conf_disconnect(pjsua_player_get_conf_port(player_id), 0);
    pjsua_recorder_destroy(writer_id);
    pjsua_player_destroy(player_id);
    player_id = PJSUA_INVALID_ID;
    writer_id = PJSUA_INVALID_ID;

    /*
     * Play the result.
     */
    status = pjsua_player_create(
                 pj_cstr(&tmp, add_path(doc_path, AEC_REC_PATH)),
                 0, &player_id);
    if (status != PJ_SUCCESS) {
	PJ_PERROR(1,(THIS_FILE, status, "Error opening WAV file %s", AEC_REC_PATH));
	goto on_return;
    }
    pjsua_conf_connect(pjsua_player_get_conf_port(player_id), 0);

    /* Wait user signal */
    gui_msgbox(title, "We are now playing the captured audio from the mic. "
		      "Check if echo (of the audio played back previously) is "
		      "present in the audio. The recording is stored in "
		      AEC_REC_PATH " for offline analysis. "
		      "Press OK to stop.",
		      WITH_OK);

    pjsua_conf_disconnect(pjsua_player_get_conf_port(player_id), 0);

    key = gui_msgbox(title,
		     "Did you notice any echo in the recording?",
		     WITH_YESNO);


on_return:
    if (player_id != PJSUA_INVALID_ID)
	pjsua_player_destroy(player_id);
    if (writer_id != PJSUA_INVALID_ID)
	pjsua_recorder_destroy(writer_id);

    /* Wait until sound device closed before restoring back EC tail setting */
    while (pjsua_snd_is_active())
	pj_thread_sleep(10);
    pjsua_set_ec(last_ec_tail, 0);


    if (status != PJ_SUCCESS) {
	systest_perror("Sorry we encountered an error: ", status);
	ti->success = PJ_FALSE;
	pj_strerror(status, ti->reason, sizeof(ti->reason));
    } else if (key == KEY_YES) {
	ti->success = PJ_FALSE;
	if (!ti->success) {
	    pj_ansi_strcpy(ti->reason, USER_ERROR);
	}
    } else {
	char msg[200];

	pj_ansi_snprintf(msg, sizeof(msg), "Test succeeded.\r\n");

	ti->success = PJ_TRUE;
	pj_ansi_strncpy(ti->reason, msg, sizeof(ti->reason));
	ti->reason[sizeof(ti->reason)-1] = '\0';
    }
}
예제 #10
0
static void systest_latency_test(void)
{
    const char *ref_wav_paths[] = { add_path(res_path, WAV_TOCK8_PATH), ALT_PATH1 WAV_TOCK8_PATH };
    pj_str_t rec_wav_file;
    pjsua_player_id play_id = PJSUA_INVALID_ID;
    pjsua_conf_port_id play_slot = PJSUA_INVALID_ID;
    pjsua_recorder_id rec_id = PJSUA_INVALID_ID;
    pjsua_conf_port_id rec_slot = PJSUA_INVALID_ID;
    pj_pool_t *pool = NULL;
    pjmedia_port *wav_port = NULL;
    unsigned lat_sum=0, lat_cnt=0, lat_min=0, lat_max=0;
    enum gui_key key;
    test_item_t *ti;
    const char *title = "Audio Latency Test";
    pj_status_t status;

    ti = systest_alloc_test_item(title);
    if (!ti)
	return;

    key = gui_msgbox(title,
		     "This test will try to find the audio device's "
		     "latency. We will play a special WAV file to the "
		     "speaker for ten seconds, then at the end "
		     "calculate the latency. Please don't do anything "
		     "until the test is done.", WITH_OKCANCEL);
    if (key != KEY_OK) {
	ti->skipped = PJ_TRUE;
	return;
    }
    key = gui_msgbox(title,
		     "For this test to work, we must be able to capture "
		     "the audio played in the speaker (the echo), and only"
		     " that audio (i.e. you must be in relatively quiet "
		     "place to run this test). "
		     "Press OK to start, or CANCEL to skip.",
		     WITH_OKCANCEL);
    if (key != KEY_OK) {
	ti->skipped = PJ_TRUE;
	return;
    }

    PJ_LOG(3,(THIS_FILE, "Running %s", title));

    status = create_player(PJ_ARRAY_SIZE(ref_wav_paths), ref_wav_paths,
			   &play_id);
    if (status != PJ_SUCCESS)
	goto on_return;

    play_slot = pjsua_player_get_conf_port(play_id);

    rec_wav_file = pj_str(add_path(doc_path, WAV_LATENCY_OUT_PATH));
    status = pjsua_recorder_create(&rec_wav_file, 0, NULL, -1, 0, &rec_id);
    if (status != PJ_SUCCESS)
	goto on_return;

    rec_slot = pjsua_recorder_get_conf_port(rec_id);

    /* Setup the test */
    //status = pjsua_conf_connect(0, 0);
    status = pjsua_conf_connect(play_slot, 0);
    status = pjsua_conf_connect(0, rec_slot);
    status = pjsua_conf_connect(play_slot, rec_slot);


    /* We're running */
    PJ_LOG(3,(THIS_FILE, "Please wait while test is running (~10 sec)"));
    gui_sleep(10);

    /* Done with the test */
    //status = pjsua_conf_disconnect(0, 0);
    status = pjsua_conf_disconnect(play_slot, rec_slot);
    status = pjsua_conf_disconnect(0, rec_slot);
    status = pjsua_conf_disconnect(play_slot, 0);

    pjsua_recorder_destroy(rec_id);
    rec_id = PJSUA_INVALID_ID;

    pjsua_player_destroy(play_id);
    play_id = PJSUA_INVALID_ID;

    /* Confirm that echo is heard */
    gui_msgbox(title,
	       "Test is done. Now we need to confirm that we indeed "
	       "captured the echo. We will play the captured audio "
	       "and please confirm that you can hear the 'tock' echo.",
	       WITH_OK);

    status = pjsua_player_create(&rec_wav_file, 0, &play_id);
    if (status != PJ_SUCCESS)
	goto on_return;

    play_slot = pjsua_player_get_conf_port(play_id);

    status = pjsua_conf_connect(play_slot, 0);
    if (status != PJ_SUCCESS)
	goto on_return;

    key = gui_msgbox(title,
		     "The captured audio is being played back now. "
		     "Can you hear the 'tock' echo?",
		     WITH_YESNO);

    pjsua_player_destroy(play_id);
    play_id = PJSUA_INVALID_ID;

    if (key != KEY_YES)
	goto on_return;

    /* Now analyze the latency */
    pool = pjsua_pool_create("latency", 512, 512);

    status = pjmedia_wav_player_port_create(pool, rec_wav_file.ptr, 0, 0, 0, &wav_port);
    if (status != PJ_SUCCESS)
	goto on_return;

    status = calculate_latency(pool, wav_port, &lat_sum, &lat_cnt,
			       &lat_min, &lat_max);
    if (status != PJ_SUCCESS)
	goto on_return;

on_return:
    if (wav_port)
	pjmedia_port_destroy(wav_port);
    if (pool)
	pj_pool_release(pool);
    if (play_id != PJSUA_INVALID_ID)
	pjsua_player_destroy(play_id);
    if (rec_id != PJSUA_INVALID_ID)
	pjsua_recorder_destroy(rec_id);

    if (status != PJ_SUCCESS) {
	systest_perror("Sorry we encountered an error: ", status);
	ti->success = PJ_FALSE;
	pj_strerror(status, ti->reason, sizeof(ti->reason));
    } else if (key != KEY_YES) {
	ti->success = PJ_FALSE;
	if (!ti->success) {
	    pj_ansi_strcpy(ti->reason, USER_ERROR);
	}
    } else {
	char msg[200];
	pj_size_t msglen;

	pj_ansi_snprintf(msg, sizeof(msg),
			 "The sound device latency:\r\n"
			 " Min=%u, Max=%u, Avg=%u\r\n",
			 lat_min, lat_max, lat_sum/lat_cnt);
	msglen = strlen(msg);

	if (lat_sum/lat_cnt > 500) {
	    pj_ansi_snprintf(msg+msglen, sizeof(msg)-msglen,
			     "The latency is huge!\r\n");
	    msglen = strlen(msg);
	} else if (lat_sum/lat_cnt > 200) {
	    pj_ansi_snprintf(msg+msglen, sizeof(msg)-msglen,
			     "The latency is quite high\r\n");
	    msglen = strlen(msg);
	}

	key = gui_msgbox(title, msg, WITH_OK);

	ti->success = PJ_TRUE;
	pj_ansi_strncpy(ti->reason, msg, sizeof(ti->reason));
	ti->reason[sizeof(ti->reason)-1] = '\0';
    }
}
예제 #11
0
/*****************************************************************************
 * test: record audio
 */
static void systest_rec_audio(void)
{
    const pj_str_t filename = pj_str(add_path(doc_path, WAV_REC_OUT_PATH));
    pj_pool_t *pool = NULL;
    enum gui_key key;
    pjsua_recorder_id rec_id = PJSUA_INVALID_ID;
    pjsua_player_id play_id = PJSUA_INVALID_ID;
    pjsua_conf_port_id rec_slot = PJSUA_INVALID_ID;
    pjsua_conf_port_id play_slot = PJSUA_INVALID_ID;
    pj_status_t status = PJ_SUCCESS;
    const char *title = "Audio Recording";
    test_item_t *ti;

    ti = systest_alloc_test_item(title);
    if (!ti)
	return;

    key = gui_msgbox(title,
		     "This test will allow you to record audio "
		     "from the microphone, and playback the "
		     "audio to the speaker. Press OK to start recording, "
		     "CANCEL to skip.",
		     WITH_OKCANCEL);
    if (key != KEY_OK) {
	ti->skipped = PJ_TRUE;
	return;
    }

    PJ_LOG(3,(THIS_FILE, "Running %s", title));

    pool = pjsua_pool_create("rectest", 512, 512);

    status = pjsua_recorder_create(&filename, 0, NULL, -1, 0, &rec_id);
    if (status != PJ_SUCCESS)
	goto on_return;

    rec_slot = pjsua_recorder_get_conf_port(rec_id);

    status = pjsua_conf_connect(0, rec_slot);
    if (status != PJ_SUCCESS)
	goto on_return;

    key = gui_msgbox(title,
		     "Recording is in progress now, please say "
		     "something in the microphone. Press OK "
		     "to stop recording", WITH_OK);

    pjsua_conf_disconnect(0, rec_slot);
    rec_slot = PJSUA_INVALID_ID;
    pjsua_recorder_destroy(rec_id);
    rec_id = PJSUA_INVALID_ID;

    status = pjsua_player_create(&filename, 0, &play_id);
    if (status != PJ_SUCCESS)
	goto on_return;

    play_slot = pjsua_player_get_conf_port(play_id);

    status = pjsua_conf_connect(play_slot, 0);
    if (status != PJ_SUCCESS)
	goto on_return;

    key = gui_msgbox(title,
		     "Recording has been stopped. "
		     "The recorded audio is being played now to "
		     "the speaker device, in a loop. Listen for "
		     "any audio impairments. Press OK to stop.",
		     WITH_OK);

on_return:
    if (rec_slot != PJSUA_INVALID_ID)
	pjsua_conf_disconnect(0, rec_slot);
    if (rec_id != PJSUA_INVALID_ID)
	pjsua_recorder_destroy(rec_id);
    if (play_slot != PJSUA_INVALID_ID)
	pjsua_conf_disconnect(play_slot, 0);
    if (play_id != PJSUA_INVALID_ID)
	pjsua_player_destroy(play_id);
    if (pool)
	pj_pool_release(pool);

    if (status != PJ_SUCCESS) {
	systest_perror("Sorry we encountered an error: ", status);
	ti->success = PJ_FALSE;
	pj_strerror(status, ti->reason, sizeof(ti->reason));
    } else {
	key = gui_msgbox(title, "Is the audio okay?", WITH_YESNO);
	ti->success = (key == KEY_YES);
	if (!ti->success) {
	    pj_ansi_snprintf(textbuf, sizeof(textbuf),
			     "You will probably need to copy the recorded "
			     "WAV file %s to a desktop computer and analyze "
			     "it, to find out whether it's a recording "
			     "or playback problem.",
			     WAV_REC_OUT_PATH);
	    gui_msgbox(title, textbuf, WITH_OK);
	    pj_ansi_strcpy(ti->reason, USER_ERROR);
	}
    }
}