예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
파일: qvdoorcom.cpp 프로젝트: l0wside/qvisu
void QVDoorcom::onCallState(int call_id, QString state) {
    if (call_id != active_call) {
        return;
    }
    qDebug() << "new state" << state;
    if (state == "DISCONNCTD") {
        popup->hide();
        active_call = -1;
//        pjsua_conf_adjust_tx_level(0,0.0);
    }
    if (state == "CONFIRMED") {
        w_dooropen->show();

        /* Create DTMF generator */
        pjsua_call_info ci;

        qDebug() << "2" << pjmedia_tonegen_create(pj_pool, 16000, 1, 160, 16, 0, &pj_tonegen);
        qDebug() << "3" << pjsua_conf_add_port(pj_pool, pj_tonegen, &pj_toneslot);

        pjsua_call_get_info(call_id, &ci);
        qDebug() << "4" << pjsua_conf_connect(pj_toneslot, ci.conf_slot);


        /* Send DTMF code */
        if (!code_accept.isEmpty()) {
            qDebug() << "accept code" << code_accept;

            pjmedia_tone_digit d[16];
            unsigned i, count = code_accept.length();

            if (count > PJ_ARRAY_SIZE(d)) {
                count = PJ_ARRAY_SIZE(d);
            }

            pj_bzero(d, sizeof(d));
            for (i=0; i<count; i++) {
                d[i].digit = code_accept.at(i).toLatin1();
                d[i].on_msec = 80;
                d[i].off_msec = 80;
                d[i].volume = 32767;
            }

            qDebug() << "before tonegen";
            qDebug() << "tonegen result " << pjmedia_tonegen_play_digits(pj_tonegen, count, d, 0);
            dtmf_timer.start();
        }
    }
}
예제 #4
0
void init_ringback_tone(){
	pj_status_t status;
	pj_str_t name;
	pjmedia_tone_desc tone[RINGBACK_CNT];
	unsigned i;

	app_config.pool = pjsua_pool_create("pjsua-jni", 1000, 1000);
	app_config.ringback_slot=PJSUA_INVALID_ID;
	app_config.ringback_on = PJ_FALSE;
	app_config.ringback_cnt = 0;

	//Ringback
	name = pj_str((char *)"ringback");
	status = pjmedia_tonegen_create2(app_config.pool, &name,
					 16000,
					 1,
					 320,
					 16, PJMEDIA_TONEGEN_LOOP,
					 &app_config.ringback_port);
	if (status != PJ_SUCCESS){
		goto on_error;
	}

	pj_bzero(&tone, sizeof(tone));
	for (i=0; i<RINGBACK_CNT; ++i) {
		tone[i].freq1 = RINGBACK_FREQ1;
		tone[i].freq2 = RINGBACK_FREQ2;
		tone[i].on_msec = RINGBACK_ON;
		tone[i].off_msec = RINGBACK_OFF;
	}
	tone[RINGBACK_CNT-1].off_msec = RINGBACK_INTERVAL;
	pjmedia_tonegen_play(app_config.ringback_port, RINGBACK_CNT, tone, PJMEDIA_TONEGEN_LOOP);
	status = pjsua_conf_add_port(app_config.pool, app_config.ringback_port,
					 &app_config.ringback_slot);
	if (status != PJ_SUCCESS){
		goto on_error;
	}
	return;

	on_error :{
		pj_pool_release(app_config.pool);
	}
}
예제 #5
0
bool SipPhone::init_pjmedia() {
#if 0
  Logger::debug("SipPhone::init_pjmedia...");
#define CLOCK_RATE        8000
#define CHANNEL_COUNT     1
#define SAMPLES_PER_FRAME ((CLOCK_RATE * CHANNEL_COUNT * PJSUA_DEFAULT_AUDIO_FRAME_PTIME) / 1000)

  pj_status_t status = pjmedia_null_port_create(m_Pool, CLOCK_RATE, 1, SAMPLES_PER_FRAME, 16, &m_mediaPortSilence);
  if (status != PJ_SUCCESS) {
    Logger::error("pjmedia_null_port_create() failed (%s)", Helper::getPjStatusAsString(status).c_str());
    return false;
  }

  status = pjsua_conf_add_port(m_Pool, m_mediaPortSilence, &m_mediaConfSilenceId);
  if (status != PJ_SUCCESS) {
    Logger::error("pjsua_conf_add_port() failed (%s)", Helper::getPjStatusAsString(status).c_str());
    return false;
  }
#endif
  return true;
}
예제 #6
0
/*****************************************************************************
 * test: play simple ringback tone and hear it
 */
static void systest_play_tone(void)
{
    /* Ringtones  */
    #define RINGBACK_FREQ1	    440	    /* 400 */
    #define RINGBACK_FREQ2	    480	    /* 450 */
    #define RINGBACK_ON		    3000    /* 400 */
    #define RINGBACK_OFF	    4000    /* 200 */
    #define RINGBACK_CNT	    1	    /* 2   */
    #define RINGBACK_INTERVAL	    4000    /* 2000 */

    unsigned i, samples_per_frame;
    pjmedia_tone_desc tone[RINGBACK_CNT];
    pj_pool_t *pool = NULL;
    pjmedia_port *ringback_port = NULL;
    enum gui_key key;
    int ringback_slot = -1;
    test_item_t *ti;
    pj_str_t name;
    const char *title = "Audio Tone Playback Test";
    pj_status_t status;

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

    key = gui_msgbox(title,
		     "This test will play simple ringback tone to "
		     "the speaker. Please listen carefully for audio "
		     "impairments such as stutter. You may need "
		     "to let this test running for a while to "
		     "make sure that everything is okay. Press "
		     "OK to start, 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("ringback", 512, 512);
    samples_per_frame = systest.media_cfg.audio_frame_ptime *
			systest.media_cfg.clock_rate *
			systest.media_cfg.channel_count / 1000;

    /* Ringback tone (call is ringing) */
    name = pj_str("ringback");
    status = pjmedia_tonegen_create2(pool, &name,
				     systest.media_cfg.clock_rate,
				     systest.media_cfg.channel_count,
				     samples_per_frame,
				     16, PJMEDIA_TONEGEN_LOOP,
				     &ringback_port);
    if (status != PJ_SUCCESS)
	goto on_return;

    pj_bzero(&tone, sizeof(tone));
    for (i=0; i<RINGBACK_CNT; ++i) {
	tone[i].freq1 = RINGBACK_FREQ1;
	tone[i].freq2 = RINGBACK_FREQ2;
	tone[i].on_msec = RINGBACK_ON;
	tone[i].off_msec = RINGBACK_OFF;
    }
    tone[RINGBACK_CNT-1].off_msec = RINGBACK_INTERVAL;

    status = pjmedia_tonegen_play(ringback_port, RINGBACK_CNT, tone,
				  PJMEDIA_TONEGEN_LOOP);
    if (status != PJ_SUCCESS)
	goto on_return;

    status = pjsua_conf_add_port(pool, ringback_port, &ringback_slot);
    if (status != PJ_SUCCESS)
	goto on_return;

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

    key = gui_msgbox(title,
		     "Ringback tone should be playing now in the "
		     "speaker. Press OK to stop. ", WITH_OK);

    status = PJ_SUCCESS;

on_return:
    if (ringback_slot != -1)
	pjsua_conf_remove_port(ringback_slot);
    if (ringback_port)
	pjmedia_port_destroy(ringback_port);
    if (pool)
	pj_pool_release(pool);

    if (status != PJ_SUCCESS) {
	systest_perror("Sorry we encounter error when initializing "
		       "the tone generator: ", 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_strcpy(ti->reason, USER_ERROR);
    }
    return;
}
예제 #7
0
파일: qvdoorcom.cpp 프로젝트: l0wside/qvisu
QVDoorcom::QVDoorcom(QDomElement xml_desc, QString container, QWidget *parent) :
    QVElement(xml_desc,container,parent)
{
    if (w < 1) {
        w = 1;
    }
    if (h < 1) {
        h = 1;
    }
    popup = 0;
    if (instance_count > 0) {
        w = h = 0;
        return;
    }
    instance_count = 1;
    doorcom = this;

    popup = new QVPopupFrame(parent);

    QDomElement e_server = xml_desc.firstChildElement("server");
    QDomElement e_user = xml_desc.firstChildElement("user");
    QDomElement e_password = xml_desc.firstChildElement("password");
    if (e_server.isNull() || e_user.isNull() || e_password.isNull()) {
        qDebug() << "SIP client: insufficient auth info";
        return;
    }

    QString s_server = e_server.text();
    QString s_user = e_user.text();
    QString s_password = e_password.text();

    QDomElement e_caller = xml_desc.firstChildElement("source");
    if (!e_caller.isNull()) {
        accepted_caller = e_caller.text();
    }

    QDomElement e_accept = xml_desc.firstChildElement("accept");
    if (!e_accept.isNull()) {
        code_accept = e_accept.text();
    }

    QDomElement e_hangup = xml_desc.firstChildElement("hangup");
    if (!e_hangup.isNull()) {
        code_hangup = e_hangup.text();
    }

    QDomElement e_dooropen = xml_desc.firstChildElement("dooropen");
    if (!e_dooropen.isNull()) {
        code_dooropen = e_dooropen.text();
    }

    QFile f_doorbell;
    QString s_doorbell_name;
    bool doorbell_ok;
    bell_wav = 0;
    QDomElement e_doorbell = xml_desc.firstChildElement("ringtone");
    if (!e_doorbell.isNull()) {
        s_doorbell_name = findFilePath(e_doorbell.text());
        f_doorbell.setFileName(findFilePath(e_doorbell.text()));
        f_doorbell.open(QIODevice::ReadOnly);
    }
    if (!f_doorbell.isOpen()) {
        f_doorbell.setFileName(":/sounds/doorbell.wav");
        f_doorbell.open(QIODevice::ReadOnly);
    }

#ifndef DOORBELL_WAV
    QByteArray riff = f_doorbell.read(12);
    if (riff.length() < 12) {
        doorbell_ok = false;
    } else {
        if (!riff.startsWith("RIFF") || !riff.endsWith("WAVE")) {
            doorbell_ok = false;
        }
    }

    QByteArray fmthdr = f_doorbell.read(8);
    if (!fmthdr.startsWith("fmt")) {
        doorbell_ok = false;
    }
    uint32_t fmt_len;
    memcpy(&fmt_len,fmthdr.mid(4).data(),4);
    qDebug() << "fmt len" << fmt_len;
    if (fmt_len < 16) {
        doorbell_ok = false;
    }
    QByteArray fmt = f_doorbell.read(fmt_len);
    uint16_t audio_format;
    uint16_t num_channels;
    uint32_t sample_rate;
    uint32_t byte_rate;
    uint16_t block_align;
    uint16_t bits_per_sample;
    uint32_t bell_datalen;

#if (BYTE_ORDER != __LITTLE_ENDIAN)
#error Adapt endianness in __FILE__
#endif

    if (fmt.length() < fmt_len) {
        doorbell_ok = false;
    } else {
        memcpy(&audio_format,fmt.mid(0).data(),2);
        memcpy(&num_channels,fmt.mid(2).data(),2);
        memcpy(&sample_rate,fmt.mid(4).data(),4);
        memcpy(&byte_rate,fmt.mid(8).data(),4);
        memcpy(&block_align,fmt.mid(12).data(),2);
        memcpy(&bits_per_sample,fmt.mid(14).data(),2);
    }

    qDebug() << audio_format << "nch" << num_channels << "samplerate" << sample_rate << "byztera" << byte_rate << "blocka" << block_align << "bps" << bits_per_sample;
    if (audio_format != 0x0001) {
        doorbell_ok = false;
    }

    if (doorbell_ok) {
        QByteArray datahdr = f_doorbell.read(8);
        if (!datahdr.startsWith("data") || (datahdr.length() < 8)) {
            doorbell_ok = false;
        } else {
            memcpy(&bell_datalen,datahdr.mid(4).data(),4);
        }
        if (doorbell_ok && (bell_datalen > 0)) {
            QByteArray data = f_doorbell.read(bell_datalen);
            bell_wav = (char*)malloc(bell_datalen);
            if (bell_wav != 0) {
                memcpy(bell_wav,data.data(),bell_datalen);
            }
        }
    }
#endif

    active_call = -1;

    QObject::connect(this,SIGNAL(incomingCall(int)),this,SLOT(onIncomingCall(int)),Qt::QueuedConnection);
    QObject::connect(this,SIGNAL(callState(int,QString)),this,SLOT(onCallState(int,QString)),Qt::QueuedConnection);
    QObject::connect(this,SIGNAL(callMediaState(int)),this,SLOT(onCallMediaState(int)),Qt::QueuedConnection);

    w_accept = new QVSvgWidget(":/icons/phone_call.svg",popup->content());
    w_hangup = new QVSvgWidget(":/icons/phone_call_end.svg",popup->content());
    w_dooropen = new QVSvgWidget(":/icons/door_open.svg",popup->content());
    QObject::connect(w_accept,SIGNAL(clicked(double,double)),this,SLOT(onAcceptPressed()));
    QObject::connect(w_hangup,SIGNAL(clicked(double,double)),this,SLOT(onHangupPressed()));
    QObject::connect(w_dooropen,SIGNAL(clicked(double,double)),this,SLOT(onDoorOpenPressed()));

    hangup_timer.setSingleShot(true);
    hangup_timer.setInterval(800);
    QObject::connect(&hangup_timer,SIGNAL(timeout()),this,SLOT(onHangupTimer()));

    dtmf_timer.setSingleShot(true);
    dtmf_timer.setInterval(200);
    QObject::connect(&dtmf_timer,SIGNAL(timeout()),this,SLOT(onDTMFTimer()));

    /******* Init PJSUA ********/
    pjsua_acc_id acc_id;
    pj_status_t status;

    /* Create pjsua first! */
    status = pjsua_create();
    if (status != PJ_SUCCESS) {
        qDebug() << "Cannot create PJSUA SIP client, cause:" << status;
        return;
    }

    /* Init pjsua */
    pjsua_config cfg;
    pjsua_logging_config log_cfg;
    pjsua_media_config media_cfg;

    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;

    pjsua_logging_config_default(&log_cfg);
    log_cfg.console_level = 1;

    pjsua_media_config_default(&media_cfg);
    media_cfg.clock_rate = 8000;
    media_cfg.ec_tail_len = 0;

    status = pjsua_init(&cfg, &log_cfg, &media_cfg);
    if (status != PJ_SUCCESS) {
        qDebug() << "Cannot init PJSUA SIP client, cause: " << status;
        return;
    }

    /* Add UDP transport. */
    pjsua_transport_config transport_cfg;

    pjsua_transport_config_default(&transport_cfg);
    transport_cfg.port = 5060;
    status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &transport_cfg, NULL);
    if (status != PJ_SUCCESS) {
        qDebug() << "Cannot init PJSUA UDP transport, cause: " << status;
        return;
    }

    /* Initialization is done, now start pjsua */
    status = pjsua_start();
    if (status != PJ_SUCCESS) {
        qDebug() << "Cannot start PJSUA SIP client, cause: " << status;
        return;
    }
    /* Register to SIP server by creating SIP account. */
    pjsua_acc_config acc_cfg;

    pjsua_acc_config_default(&acc_cfg);
    QString s_id = "sip:" + s_user + "@" + s_server;
    QString s_uri = "sip:" + s_server;
    acc_cfg.cred_count = 1;
    acc_cfg.cred_info[0].realm = pj_str(strdup(s_server.toLocal8Bit().data()));
    acc_cfg.cred_info[0].scheme = pj_str("digest");
    acc_cfg.cred_info[0].username = pj_str(strdup(s_user.toLocal8Bit().data()));
    acc_cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
    acc_cfg.cred_info[0].data = pj_str(strdup(s_password.toLocal8Bit().data()));
    acc_cfg.id = pj_str(strdup(s_id.toLocal8Bit().data()));
    acc_cfg.reg_uri = pj_str(strdup(s_uri.toLocal8Bit().data()));
    status = pjsua_acc_add(&acc_cfg, PJ_TRUE, &acc_id);
    if (status != PJ_SUCCESS) {
        qDebug() << "PJSUA auth data invalid, cause: " << status;
        return;
    }

    qDebug() << "PJSUA ports" << pjsua_conf_get_active_ports();
    pjsua_conf_port_info info;
    pjsua_conf_get_port_info (0, &info);
    qDebug() << pj2qstring(info.name);

//    pjsua_conf_adjust_tx_level(0,0.0);

    pj_caching_pool_init(&pj_cpool, &pj_pool_factory_default_policy, 0);
    pj_pool = pjsua_pool_create("qvisu", 8192, 8192);

#ifndef DOORBELL_WAV
    if (doorbell_ok && (bell_wav != 0)) {
        status = pjmedia_mem_player_create(pj_pool,
                                           bell_wav,
                                           bell_datalen,
                                           sample_rate,
                                           num_channels,
                                           16384,
                                           bits_per_sample,
                                           0,//PJMEDIA_MEM_NO_LOOP,
                                           &bell_file_port);

        qDebug() << "Bell memory player" << status;

        status = pjsua_conf_add_port(pj_pool,bell_file_port,&bell_port_id);
        qDebug() << "bell file add status" << status << "id" << bell_port_id;

        status = pjmedia_mem_player_set_eof_cb 	(bell_file_port,
                                                 0,
                                                 &on_file_played);

    } else {
        bell_file_port = 0;
    }
#else
    qDebug() << "Doorbell file" << s_doorbell_name;
    if (s_doorbell_name.isEmpty()) {
        bell_file_port = 0;
    } else {
        /* Create file media port for doorbell from the WAV file */
        status = pjmedia_wav_player_port_create(pj_pool,	/* memory pool	    */
                                                strdup(s_doorbell_name.toUtf8().data()),	/* file to play	    */
                                                20,	/* ptime.	    */
                                                PJMEDIA_FILE_NO_LOOP,	/* flags	    */
                                                0,	/* default buffer   */
                                                &bell_file_port/* returned port    */
                                                );
        if (status != PJ_SUCCESS) {
            qDebug() << "Cannot open wav file" << status;
            bell_file_port = 0;
        }
    }

    if (bell_file_port != 0) {
        status = pjsua_conf_add_port(pj_pool,bell_file_port,&bell_port_id);
        qDebug() << "bell file add status" << status << "id" << bell_port_id;

        status = pjmedia_wav_player_set_eof_cb 	(bell_file_port,
                                                 0,
                                                 &on_file_played);
        if (status != PJ_SUCCESS) {
            qDebug() << "Cannot register callback";
            bell_file_port = 0;
        }
    }
#endif
}