Example #1
0
static pj_status_t job_queue_create(pj_pool_t *pool, job_queue **pjq)
{
    unsigned i;
    pj_status_t status;
    
    job_queue *jq = PJ_POOL_ZALLOC_T(pool, job_queue);
    jq->size = MAX_JOBS;
    status = pj_sem_create(pool, "thread_sem", 0, jq->size + 1, &jq->sem);
    if (status != PJ_SUCCESS)
        goto on_error;

    for (i = 0; i < jq->size; i++) {
        status = pj_sem_create(pool, "job_sem", 0, 1, &jq->job_sem[i]);
        if (status != PJ_SUCCESS)
            goto on_error;
    }
    
    status = pj_mutex_create_recursive(pool, "job_mutex", &jq->mutex);
    if (status != PJ_SUCCESS)
        goto on_error;
    
    status = pj_thread_create(pool, "job_th", job_thread, jq, 0, 0,
                              &jq->thread);
    if (status != PJ_SUCCESS)
        goto on_error;
    
    *pjq = jq;
    return PJ_SUCCESS;
    
on_error:
    job_queue_destroy(jq);
    return status;
}
Example #2
0
/*
 * Create reader/writer mutex.
 *
 */
PJ_DEF(pj_status_t) pj_rwmutex_create(pj_pool_t *pool, const char *name,
				      pj_rwmutex_t **p_mutex)
{
    pj_status_t status;
    pj_rwmutex_t *rwmutex;

    PJ_ASSERT_RETURN(pool && p_mutex, PJ_EINVAL);

    *p_mutex = NULL;
    rwmutex = PJ_POOL_ALLOC_T(pool, pj_rwmutex_t);

    status = pj_mutex_create_simple(pool, name, &rwmutex ->read_lock);
    if (status != PJ_SUCCESS)
	return status;

    status = pj_sem_create(pool, name, 1, 1, &rwmutex->write_lock);
    if (status != PJ_SUCCESS) {
	pj_mutex_destroy(rwmutex->read_lock);
	return status;
    }

    rwmutex->reader_count = 0;
    *p_mutex = rwmutex;
    return PJ_SUCCESS;
}
Example #3
0
PJ_DEF(pj_status_t) pj_lock_create_semaphore(  pj_pool_t *pool,
					       const char *name,
					       unsigned initial,
					       unsigned max,
					       pj_lock_t **lock )
{
    pj_lock_t *p_lock;
    pj_sem_t *sem;
    pj_status_t rc;

    PJ_ASSERT_RETURN(pool && lock, PJ_EINVAL);

    p_lock = PJ_POOL_ALLOC_T(pool, pj_lock_t);
    if (!p_lock)
	return PJ_ENOMEM;

    pj_memcpy(p_lock, &sem_lock_template, sizeof(pj_lock_t));
    rc = pj_sem_create( pool, name, initial, max, &sem);
    if (rc != PJ_SUCCESS)
        return rc;

    p_lock->lock_object = sem;
    *lock = p_lock;

    return PJ_SUCCESS;
}
Example #4
0
static int semaphore_test(pj_pool_t *pool)
{
    pj_sem_t *sem;
    pj_status_t status;

    PJ_LOG(3,("", "...testing semaphore"));

    status = pj_sem_create(pool, NULL, 0, 1, &sem);
    if (status != PJ_SUCCESS) {
	app_perror("...error: pj_sem_create()", status);
	return -151;
    }

    status = pj_sem_post(sem);
    if (status != PJ_SUCCESS) {
	app_perror("...error: pj_sem_post()", status);
	pj_sem_destroy(sem);
	return -153;
    }

    status = pj_sem_trywait(sem);
    if (status != PJ_SUCCESS) {
	app_perror("...error: pj_sem_trywait()", status);
	pj_sem_destroy(sem);
	return -156;
    }

    status = pj_sem_post(sem);
    if (status != PJ_SUCCESS) {
	app_perror("...error: pj_sem_post()", status);
	pj_sem_destroy(sem);
	return -159;
    }

    status = pj_sem_wait(sem);
    if (status != PJ_SUCCESS) {
	app_perror("...error: pj_sem_wait()", status);
	pj_sem_destroy(sem);
	return -161;
    }

    status = pj_sem_destroy(sem);
    if (status != PJ_SUCCESS) {
	app_perror("...error: pj_sem_destroy()", status);
	return -163;
    }

    return 0;
}
Example #5
0
PJ_DEF(pj_status_t) pjmedia_event_mgr_create(pj_pool_t *pool,
                                             unsigned options,
				             pjmedia_event_mgr **p_mgr)
{
    pjmedia_event_mgr *mgr;
    pj_status_t status;

    mgr = PJ_POOL_ZALLOC_T(pool, pjmedia_event_mgr);
    mgr->pool = pj_pool_create(pool->factory, "evt mgr", 500, 500, NULL);
    pj_list_init(&mgr->esub_list);
    pj_list_init(&mgr->free_esub_list);

    if (!(options & PJMEDIA_EVENT_MGR_NO_THREAD)) {
        status = pj_sem_create(mgr->pool, "ev_sem", 0, MAX_EVENTS + 1,
                               &mgr->sem);
        if (status != PJ_SUCCESS)
            return status;

        status = pj_thread_create(mgr->pool, "ev_thread",
                                  &event_worker_thread,
                                  mgr, 0, 0, &mgr->thread);
        if (status != PJ_SUCCESS) {
            pjmedia_event_mgr_destroy(mgr);
            return status;
        }
    }

    status = pj_mutex_create_recursive(mgr->pool, "ev_mutex", &mgr->mutex);
    if (status != PJ_SUCCESS) {
        pjmedia_event_mgr_destroy(mgr);
        return status;
    }

    if (!event_manager_instance)
	event_manager_instance = mgr;

    if (p_mgr)
	*p_mgr = mgr;

    return PJ_SUCCESS;
}
Example #6
0
static int run_client_test(const char *title,

			   pj_bool_t server_responding,
			   pj_stun_auth_type server_auth_type,

			   pj_stun_auth_type client_auth_type,
			   const char *realm,
			   const char *username,
			   const char *nonce,
			   const char *password,
			   pj_bool_t dummy_mi,

			   pj_bool_t expected_error,
			   pj_status_t expected_code,
			   const char *expected_realm,
			   const char *expected_nonce,
			   
			   int (*more_check)(void))
{
    pj_pool_t *pool;
    pj_stun_session_cb sess_cb;
    pj_stun_auth_cred cred;
    pj_stun_tx_data *tdata;
    pj_status_t status;
    int rc = 0;
    
    PJ_LOG(3,(THIS_FILE, "   %s test", title));

    /* Create client */
    pool = pj_pool_create(mem, "client", 1000, 1000, NULL);
    client = PJ_POOL_ZALLOC_T(pool, struct client);
    client->pool = pool;
    client->responding = PJ_TRUE;

    /* Create STUN session */
    pj_bzero(&sess_cb, sizeof(sess_cb));
    sess_cb.on_request_complete = &client_on_request_complete;
    sess_cb.on_send_msg = &client_send_msg;
    status = pj_stun_session_create(&stun_cfg, "client", &sess_cb, PJ_FALSE, NULL, &client->sess);
    if (status != PJ_SUCCESS) {
	destroy_client_server();
	return -200;
    }

    /* Create semaphore */
    status = pj_sem_create(pool, "client", 0, 1, &client->test_complete);
    if (status != PJ_SUCCESS) {
	destroy_client_server();
	return -205;
    }

    /* Create client socket */
    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &client->sock);
    if (status != PJ_SUCCESS) {
	destroy_client_server();
	return -210;
    }

    /* Bind client socket */
    status = pj_sock_bind_in(client->sock, 0, 0);
    if (status != PJ_SUCCESS) {
	destroy_client_server();
	return -220;
    }

    /* Create client thread */
    status = pj_thread_create(pool, "client", &client_thread, NULL, 0, 0, &client->thread);
    if (status != PJ_SUCCESS) {
	destroy_client_server();
	return -230;
    }

    /* Initialize credential */
    pj_bzero(&cred, sizeof(cred));
    cred.type = PJ_STUN_AUTH_CRED_STATIC;
    if (realm) cred.data.static_cred.realm = pj_str((char*)realm);
    if (username) cred.data.static_cred.username = pj_str((char*)username);
    if (nonce) cred.data.static_cred.nonce = pj_str((char*)nonce);
    if (password) cred.data.static_cred.data = pj_str((char*)password);
    cred.data.static_cred.data_type = PJ_STUN_PASSWD_PLAIN;
    status = pj_stun_session_set_credential(client->sess, client_auth_type, &cred);
    if (status != PJ_SUCCESS) {
	destroy_client_server();
	return -240;
    }

    /* Create the server */
    status = create_std_server(server_auth_type, server_responding);
    if (status != 0) {
	destroy_client_server();
	return status;
    }

    /* Create request */
    status = pj_stun_session_create_req(client->sess, PJ_STUN_BINDING_REQUEST, 
					PJ_STUN_MAGIC, NULL, &tdata);
    if (status != PJ_SUCCESS) {
	destroy_client_server();
	return -250;
    }

    /* Add our own attributes if client authentication is set to none */
    if (client_auth_type == PJ_STUN_AUTH_NONE) {
	pj_str_t tmp;
	if (realm)
	    pj_stun_msg_add_string_attr(tdata->pool, tdata->msg, PJ_STUN_ATTR_REALM, pj_cstr(&tmp, realm));
	if (username)
	    pj_stun_msg_add_string_attr(tdata->pool, tdata->msg, PJ_STUN_ATTR_USERNAME, pj_cstr(&tmp, username));
	if (nonce)
	    pj_stun_msg_add_string_attr(tdata->pool, tdata->msg, PJ_STUN_ATTR_NONCE, pj_cstr(&tmp, nonce));
	if (password) {
	    // ignored
	}
	if (dummy_mi) {
	    pj_stun_msgint_attr *mi;

	    pj_stun_msgint_attr_create(tdata->pool, &mi);
	    pj_stun_msg_add_attr(tdata->msg, &mi->hdr);
	}
	   
    }

    /* Send the request */
    status = pj_stun_session_send_msg(client->sess, NULL, PJ_FALSE, PJ_TRUE, &server->addr,
				      pj_sockaddr_get_len(&server->addr), tdata);
    if (status != PJ_SUCCESS) {
	destroy_client_server();
	return -270;
    }

    /* Wait until test complete */
    pj_sem_wait(client->test_complete);


    /* Verify response */
    if (expected_error) {
	if (expected_code != client->response_status) {
	    char e1[PJ_ERR_MSG_SIZE], e2[PJ_ERR_MSG_SIZE];

	    pj_strerror(expected_code, e1, sizeof(e1));
	    pj_strerror(client->response_status, e2, sizeof(e2));

	    PJ_LOG(3,(THIS_FILE, "    err: expecting %d (%s) but got %d (%s) response",
		      expected_code, e1, client->response_status, e2));
	    rc = -500;
	} 

    } else {
	int res_code = 0;
	pj_stun_realm_attr *arealm;
	pj_stun_nonce_attr *anonce;

	if (client->response_status != 0) {
	    PJ_LOG(3,(THIS_FILE, "    err: expecting successful operation but got error %d", 
		      client->response_status));
	    rc = -600;
	    goto done;
	} 

	if (PJ_STUN_IS_ERROR_RESPONSE(client->response->hdr.type)) {
	    pj_stun_errcode_attr *aerr = NULL;

	    aerr = (pj_stun_errcode_attr*)
		   pj_stun_msg_find_attr(client->response, 
					 PJ_STUN_ATTR_ERROR_CODE, 0);
	    if (aerr == NULL) {
		PJ_LOG(3,(THIS_FILE, "    err: received error response without ERROR-CODE"));
		rc = -610;
		goto done;
	    }

	    res_code = aerr->err_code;
	} else {
	    res_code = 0;
	}

	/* Check that code matches */
	if (expected_code != res_code) {
	    PJ_LOG(3,(THIS_FILE, "    err: expecting response code %d but got %d",
		      expected_code, res_code));
	    rc = -620;
	    goto done;
	}

	/* Find REALM and NONCE attributes */
	arealm = (pj_stun_realm_attr*)
	         pj_stun_msg_find_attr(client->response, PJ_STUN_ATTR_REALM, 0);
	anonce = (pj_stun_nonce_attr*)
	         pj_stun_msg_find_attr(client->response, PJ_STUN_ATTR_NONCE, 0);

	if (expected_realm) {
	    if (arealm == NULL) {
		PJ_LOG(3,(THIS_FILE, "    err: expecting REALM in esponse"));
		rc = -630;
		goto done;
	    }
	    if (pj_strcmp2(&arealm->value, expected_realm)!=0) {
		PJ_LOG(3,(THIS_FILE, "    err: REALM mismatch in response"));
		rc = -640;
		goto done;
	    }
	} else {
	    if (arealm != NULL) {
		PJ_LOG(3,(THIS_FILE, "    err: non expecting REALM in response"));
		rc = -650;
		goto done;
	    }
	}

	if (expected_nonce) {
	    if (anonce == NULL) {
		PJ_LOG(3,(THIS_FILE, "    err: expecting NONCE in esponse"));
		rc = -660;
		goto done;
	    }
	    if (pj_strcmp2(&anonce->value, expected_nonce)!=0) {
		PJ_LOG(3,(THIS_FILE, "    err: NONCE mismatch in response"));
		rc = -670;
		goto done;
	    }
	} else {
	    if (anonce != NULL) {
		PJ_LOG(3,(THIS_FILE, "    err: non expecting NONCE in response"));
		rc = -680;
		goto done;
	    }
	}
    }

    /* Our tests are okay so far. Let caller do some more tests if
     * it wants to.
     */
    if (rc==0 && more_check) {
	rc = (*more_check)();
    }


done:
    destroy_client_server();
    return rc;
}
Example #7
0
/* API: create stream */
static pj_status_t android_create_stream(pjmedia_aud_dev_factory *f,
                                         const pjmedia_aud_param *param,
                                         pjmedia_aud_rec_cb rec_cb,
                                         pjmedia_aud_play_cb play_cb,
                                         void *user_data,
                                         pjmedia_aud_stream **p_aud_strm)
{
    struct android_aud_factory *pa = (struct android_aud_factory*)f;
    pj_pool_t *pool;
    struct android_aud_stream *stream;
    pj_status_t status = PJ_SUCCESS;
    int state = 0;
    int buffSize, inputBuffSizePlay, inputBuffSizeRec;
    int channelInCfg, channelOutCfg, sampleFormat;
    jmethodID constructor_method=0, bufsize_method = 0;
    jmethodID method_id = 0;
    jclass jcl;
    JNIEnv *jni_env = 0;
    pj_bool_t attached;
    
    PJ_ASSERT_RETURN(param->channel_count >= 1 && param->channel_count <= 2,
                     PJ_EINVAL);
    PJ_ASSERT_RETURN(param->bits_per_sample==8 || param->bits_per_sample==16,
                     PJ_EINVAL);
    PJ_ASSERT_RETURN(play_cb && rec_cb && p_aud_strm, PJ_EINVAL);

    pool = pj_pool_create(pa->pf, "jnistrm", 1024, 1024, NULL);
    if (!pool)
        return PJ_ENOMEM;

    PJ_LOG(4, (THIS_FILE, "Creating Android JNI stream"));
    
    stream = PJ_POOL_ZALLOC_T(pool, struct android_aud_stream);
    stream->pool = pool;
    pj_strdup2_with_null(pool, &stream->name, "JNI stream");
    stream->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
    pj_memcpy(&stream->param, param, sizeof(*param));
    stream->user_data = user_data;
    stream->rec_cb = rec_cb;
    stream->play_cb = play_cb;
    buffSize = stream->param.samples_per_frame*stream->param.bits_per_sample/8;
    stream->rec_buf_size = stream->play_buf_size = buffSize;
    channelInCfg = (param->channel_count == 1)? 16 /*CHANNEL_IN_MONO*/:
                   12 /*CHANNEL_IN_STEREO*/;
    channelOutCfg = (param->channel_count == 1)? 4 /*CHANNEL_OUT_MONO*/:
                    12 /*CHANNEL_OUT_STEREO*/;
    sampleFormat = (param->bits_per_sample == 8)? 3 /*ENCODING_PCM_8BIT*/:
                   2 /*ENCODING_PCM_16BIT*/;

    attached = attach_jvm(&jni_env);

    if (stream->dir & PJMEDIA_DIR_CAPTURE) {
        /* Find audio record class and create global ref */
        jcl = (*jni_env)->FindClass(jni_env, "android/media/AudioRecord");
        if (jcl == NULL) {
            PJ_LOG(3, (THIS_FILE, "Unable to find audio record class"));
            status = PJMEDIA_EAUD_SYSERR;
            goto on_error;
        }
        stream->record_class = (jclass)(*jni_env)->NewGlobalRef(jni_env, jcl);
        (*jni_env)->DeleteLocalRef(jni_env, jcl);
        if (stream->record_class == 0) {
            status = PJ_ENOMEM;
            goto on_error;
        }

        /* Get the min buffer size function */
        bufsize_method = (*jni_env)->GetStaticMethodID(jni_env,
                                                       stream->record_class,
                                                       "getMinBufferSize",
                                                       "(III)I");
        if (bufsize_method == 0) {
            PJ_LOG(3, (THIS_FILE, "Unable to find audio record "
                                  "getMinBufferSize() method"));
            status = PJMEDIA_EAUD_SYSERR;
            goto on_error;
        }

        inputBuffSizeRec = (*jni_env)->CallStaticIntMethod(jni_env,
                                                           stream->record_class,
                                                           bufsize_method,
                                                           param->clock_rate,
                                                           channelInCfg,
                                                           sampleFormat);
        if (inputBuffSizeRec <= 0) {
            PJ_LOG(3, (THIS_FILE, "Unsupported audio record params"));
            status = PJMEDIA_EAUD_INIT;
            goto on_error;
        }
    }
    
    if (stream->dir & PJMEDIA_DIR_PLAYBACK) {
        /* Find audio track class and create global ref */
        jcl = (*jni_env)->FindClass(jni_env, "android/media/AudioTrack");
        if (jcl == NULL) {
            PJ_LOG(3, (THIS_FILE, "Unable to find audio track class"));
            status = PJMEDIA_EAUD_SYSERR;
            goto on_error;
        }
        stream->track_class = (jclass)(*jni_env)->NewGlobalRef(jni_env, jcl);
        (*jni_env)->DeleteLocalRef(jni_env, jcl);
        if (stream->track_class == 0) {
            status = PJ_ENOMEM;
            goto on_error;
        }

        /* Get the min buffer size function */
        bufsize_method = (*jni_env)->GetStaticMethodID(jni_env,
                                                       stream->track_class,
                                                       "getMinBufferSize",
                                                       "(III)I");
        if (bufsize_method == 0) {
            PJ_LOG(3, (THIS_FILE, "Unable to find audio track "
                                  "getMinBufferSize() method"));
            status = PJMEDIA_EAUD_SYSERR;
            goto on_error;
        }
        
        inputBuffSizePlay = (*jni_env)->CallStaticIntMethod(jni_env,
                                                            stream->track_class,
                                                            bufsize_method,
                                                            param->clock_rate,
                                                            channelOutCfg,
                                                            sampleFormat);
        if (inputBuffSizePlay <= 0) {
            PJ_LOG(3, (THIS_FILE, "Unsupported audio track params"));
            status = PJMEDIA_EAUD_INIT;
            goto on_error;
        }
    }
    
    if (stream->dir & PJMEDIA_DIR_CAPTURE) {
        jthrowable exc;
        int mic_source = 0; /* DEFAULT: default audio source */

        /* Get pointer to the constructor */
        constructor_method = (*jni_env)->GetMethodID(jni_env,
                                                     stream->record_class,
                                                     "<init>", "(IIIII)V");
        if (constructor_method == 0) {
            PJ_LOG(3, (THIS_FILE, "Unable to find audio record's constructor"));
            status = PJMEDIA_EAUD_SYSERR;
            goto on_error;
        }
        
        if (mic_source == 0) {
            /* Android-L (android-21) removes __system_property_get
             * from the NDK.
	     */
	    /*           
	    char sdk_version[PROP_VALUE_MAX];
            pj_str_t pj_sdk_version;
            int sdk_v;

            __system_property_get("ro.build.version.sdk", sdk_version);
            pj_sdk_version = pj_str(sdk_version);
            sdk_v = pj_strtoul(&pj_sdk_version);
            if (sdk_v > 10)
            */
            mic_source = 7; /* VOICE_COMMUNICATION */
        }
        PJ_LOG(4, (THIS_FILE, "Using audio input source : %d", mic_source));
        
        do {
            stream->record =  (*jni_env)->NewObject(jni_env,
                                                    stream->record_class,
                                                    constructor_method,
                                                    mic_source, 
                                                    param->clock_rate,
                                                    channelInCfg,
                                                    sampleFormat,
                                                    inputBuffSizeRec);
            if (stream->record == 0) {
                PJ_LOG(3, (THIS_FILE, "Unable to create audio record object"));
                status = PJMEDIA_EAUD_INIT;
                goto on_error;
            }
        
            exc = (*jni_env)->ExceptionOccurred(jni_env);
            if (exc) {
                (*jni_env)->ExceptionDescribe(jni_env);
                (*jni_env)->ExceptionClear(jni_env);
                PJ_LOG(3, (THIS_FILE, "Failure in audio record's constructor"));
                if (mic_source == 0) {
                    status = PJMEDIA_EAUD_INIT;
                    goto on_error;
                }
                mic_source = 0;
                PJ_LOG(4, (THIS_FILE, "Trying the default audio source."));
                continue;
            }

            /* Check state */
            method_id = (*jni_env)->GetMethodID(jni_env, stream->record_class,
                                                "getState", "()I");
            if (method_id == 0) {
                PJ_LOG(3, (THIS_FILE, "Unable to find audio record getState() "
                                      "method"));
                status = PJMEDIA_EAUD_SYSERR;
                goto on_error;
            }
            state = (*jni_env)->CallIntMethod(jni_env, stream->record,
                                              method_id);
            if (state == 0) { /* STATE_UNINITIALIZED */
                PJ_LOG(3, (THIS_FILE, "Failure in initializing audio record."));
                if (mic_source == 0) {
                    status = PJMEDIA_EAUD_INIT;
                    goto on_error;
                }
                mic_source = 0;
                PJ_LOG(4, (THIS_FILE, "Trying the default audio source."));
            }
        } while (state == 0);
        
        stream->record = (*jni_env)->NewGlobalRef(jni_env, stream->record);
        if (stream->record == 0) {
            PJ_LOG(3, (THIS_FILE, "Unable to create audio record global ref."));
            status = PJMEDIA_EAUD_INIT;
            goto on_error;
        }

        status = pj_sem_create(stream->pool, NULL, 0, 1, &stream->rec_sem);
        if (status != PJ_SUCCESS)
            goto on_error;
        
        status = pj_thread_create(stream->pool, "android_recorder",
                                  AndroidRecorderCallback, stream, 0, 0,
                                  &stream->rec_thread);
        if (status != PJ_SUCCESS)
            goto on_error;

        PJ_LOG(4, (THIS_FILE, "Audio record initialized successfully."));
    }
    
    if (stream->dir & PJMEDIA_DIR_PLAYBACK) {
        jthrowable exc;
        
        /* Get pointer to the constructor */
        constructor_method = (*jni_env)->GetMethodID(jni_env,
                                                     stream->track_class,
                                                     "<init>", "(IIIIII)V");
        if (constructor_method == 0) {
            PJ_LOG(3, (THIS_FILE, "Unable to find audio track's constructor."));
            status = PJMEDIA_EAUD_SYSERR;
            goto on_error;
        }
        
        stream->track = (*jni_env)->NewObject(jni_env,
                                              stream->track_class,
                                              constructor_method,
                                              0, /* STREAM_VOICE_CALL */
                                              param->clock_rate,
                                              channelOutCfg,
                                              sampleFormat,
                                              inputBuffSizePlay,
                                              1 /* MODE_STREAM */);
        if (stream->track == 0) {
            PJ_LOG(3, (THIS_FILE, "Unable to create audio track object."));
            status = PJMEDIA_EAUD_INIT;
            goto on_error;
        }
        
        exc = (*jni_env)->ExceptionOccurred(jni_env);
        if (exc) {
            (*jni_env)->ExceptionDescribe(jni_env);
            (*jni_env)->ExceptionClear(jni_env);
            PJ_LOG(3, (THIS_FILE, "Failure in audio track's constructor"));
            status = PJMEDIA_EAUD_INIT;
            goto on_error;
        }
        
        stream->track = (*jni_env)->NewGlobalRef(jni_env, stream->track);
        if (stream->track == 0) {
            PJ_LOG(3, (THIS_FILE, "Unable to create audio track's global ref"));
            status = PJMEDIA_EAUD_INIT;
            goto on_error;
        }
        
        /* Check state */
        method_id = (*jni_env)->GetMethodID(jni_env, stream->track_class,
                                            "getState", "()I");
        if (method_id == 0) {
            PJ_LOG(3, (THIS_FILE, "Unable to find audio track getState() "
                                  "method"));
            status = PJMEDIA_EAUD_SYSERR;
            goto on_error;
        }
        state = (*jni_env)->CallIntMethod(jni_env, stream->track,
                                          method_id);
        if (state == 0) { /* STATE_UNINITIALIZED */
            PJ_LOG(3, (THIS_FILE, "Failure in initializing audio track."));
            status = PJMEDIA_EAUD_INIT;
            goto on_error;
        }

        status = pj_sem_create(stream->pool, NULL, 0, 1, &stream->play_sem);
        if (status != PJ_SUCCESS)
            goto on_error;
        
        status = pj_thread_create(stream->pool, "android_track",
                                  AndroidTrackCallback, stream, 0, 0,
                                  &stream->play_thread);
        if (status != PJ_SUCCESS)
            goto on_error;
        
        PJ_LOG(4, (THIS_FILE, "Audio track initialized successfully."));
    }

    if (param->flags & PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING) {
	strm_set_cap(&stream->base, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,
                     &param->output_vol);
    }
    
    /* Done */
    stream->base.op = &android_strm_op;
    *p_aud_strm = &stream->base;
    
    detach_jvm(attached);
    
    return PJ_SUCCESS;
    
on_error:
    detach_jvm(attached);
    strm_destroy(&stream->base);
    return status;
}
Example #8
0
static int timer_initialize()
{
    pj_status_t rc;
    pj_mutex_t* temp_mutex;

    rc = pj_mutex_create_simple(timer_pool, "zrtp_timer", &temp_mutex);
    if (rc != PJ_SUCCESS)
    {
        return rc;
    }

    pj_enter_critical_section();
    if (timer_mutex == NULL)
        timer_mutex = temp_mutex;
    else
        pj_mutex_destroy(temp_mutex);
    pj_leave_critical_section();

    pj_mutex_lock(timer_mutex);

    if (timer_initialized)
    {
        pj_mutex_unlock(timer_mutex);
        return PJ_SUCCESS;
    }

    rc = pj_timer_heap_create(timer_pool, 4, &timer);
    if (rc != PJ_SUCCESS)
    {
        goto ERROR;
    }

    rc = pj_sem_create(timer_pool, "zrtp_timer", 0, 1, &timer_sem);
    if (rc != PJ_SUCCESS)
    {
        goto ERROR;
    }

    rc = pj_thread_create(timer_pool, "zrtp_timer", &timer_thread_run, NULL,
                          PJ_THREAD_DEFAULT_STACK_SIZE, 0, &thread_run);
    if (rc != PJ_SUCCESS)
    {
        goto ERROR;
    }
    timer_initialized = 1;
    pj_mutex_unlock(timer_mutex);
    return PJ_SUCCESS;

ERROR:
    if (timer != NULL)
    {
        pj_timer_heap_destroy(timer);
        timer = NULL;
    }
    if (timer_sem != NULL)
    {
        pj_sem_destroy(timer_sem);
        timer_sem = NULL;
    }
    if (timer_mutex != NULL)
    {
        pj_mutex_unlock(timer_mutex);
        pj_mutex_destroy(timer_mutex);
        timer_mutex = NULL;
    }

    return rc;
}
Example #9
0
    //
    // Create semaphore
    //
    pj_status_t create( Pj_Pool *pool, unsigned max,
                        unsigned initial = 0, const char *name = NULL )
    {
        destroy();
	return pj_sem_create( pool->pool_(), name, initial, max, &sem_);
    }
Example #10
0
PJ_DEF(pj_status_t) pjmedia_natnl_stream_create(pj_pool_t *pool,
                                        pjsua_call *call,
                                        pjmedia_stream_info *si,
                                        natnl_stream **stream)
{
    pj_status_t status = PJ_SUCCESS;
    unsigned strm_idx = 0;
    strm_idx = call->index;

        /* TODO:
         *   - Create and start your media stream based on the parameters
         *     in si
         */

    PJ_ASSERT_RETURN(pool, PJ_EINVAL);

    PJ_LOG(4,(THIS_FILE,"natnl audio channel update..strm_idx=%d", strm_idx));

    /* Check if no media is active */
    if (si->dir != PJMEDIA_DIR_NONE) {
        /* Create session based on session info. */
#if 0
        pool = pj_pool_create(strm_pool->factory, "strm%p", 
                              NATNL_STREAM_SIZE, NATNL_STREAM_INC, NULL);
        PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
#endif

        pj_mutex_lock(call->tnl_stream_lock);
        pj_mutex_lock(call->tnl_stream_lock2);
        pj_mutex_lock(call->tnl_stream_lock3);
        // DEAN don't re-create natnl stream
        if (call->tnl_stream) {
			*stream = call->tnl_stream;
            pj_mutex_unlock(call->tnl_stream_lock3);
            pj_mutex_unlock(call->tnl_stream_lock2);
            pj_mutex_unlock(call->tnl_stream_lock);
            return PJ_SUCCESS;
		}

        call->tnl_stream = *stream = PJ_POOL_ZALLOC_T(pool, natnl_stream);
        PJ_ASSERT_RETURN(*stream != NULL, PJ_ENOMEM);
        (*stream)->call = call;
        (*stream)->own_pool = pool;
		(*stream)->med_tp = call->med_tp;
        pj_memcpy(&(*stream)->rem_addr, &si->rem_addr, sizeof(pj_sockaddr));
        pj_list_init(&(*stream)->rbuff);
		pj_list_init(&(*stream)->gcbuff);
		pj_get_timestamp(&(*stream)->last_data_or_ka);
		pj_get_timestamp(&(*stream)->last_data);
		(*stream)->rbuff_cnt = 0;

		(*stream)->rx_band = (pj_band_t *)malloc(sizeof(pj_band_t));
		(*stream)->tx_band = (pj_band_t *)malloc(sizeof(pj_band_t));
		pj_memset((*stream)->rx_band, 0, sizeof(pj_band_t));
		pj_memset((*stream)->tx_band, 0, sizeof(pj_band_t));
		pj_bandwidthSetLimited((*stream)->rx_band, PJ_FALSE);
		pj_bandwidthSetLimited((*stream)->tx_band, PJ_FALSE);

        /* Create mutex to protect jitter buffer: */
        status = pj_mutex_create_simple(pool, NULL, &(*stream)->rbuff_mutex);
        if (status != PJ_SUCCESS) {
            //pj_pool_t *tmp_pool = (*stream)->own_pool;
            (*stream)->own_pool = NULL;
            //pj_pool_release(tmp_pool);
            goto on_return;
        }

        status = pj_mutex_create_simple(pool, NULL, &(*stream)->gcbuff_mutex);
        if (status != PJ_SUCCESS) {
            (*stream)->own_pool = NULL;
            goto on_return;
        }

        /* Create semaphore */
        status = pj_sem_create(pool, "client", 0, 65535, &(*stream)->rbuff_sem);
        if (status != PJ_SUCCESS) {
            (*stream)->own_pool = NULL;
            goto on_return;
        }


        // +Roger - Create Send buffer Mutex
        status = pj_mutex_create_simple(pool, NULL, &(*stream)->sbuff_mutex);
        if (status != PJ_SUCCESS) {
            //pj_pool_t *tmp_pool = (*stream)->own_pool;
            (*stream)->own_pool = NULL;
            //pj_pool_release(tmp_pool);
            goto on_return;
        }
        //------------------------------------//

#if 0
        /* Attach our RTP and RTCP callbacks to the media transport */
        status = pjmedia_transport_attach(call_med->tp, stream, //call_med,
                                          &si->rem_addr, &si->rem_rtcp,
                                          pj_sockaddr_get_len(&si->rem_addr),
                                          &aud_rtp_cb, &aud_rtcp_cb);
#endif

    }

on_return:
    pj_mutex_unlock(call->tnl_stream_lock3);
    pj_mutex_unlock(call->tnl_stream_lock2);
    pj_mutex_unlock(call->tnl_stream_lock);

    return status;
}