예제 #1
0
static int _tdav_audiounit_handle_signal_xxx_prepared(tdav_audiounit_handle_t* self, tsk_bool_t consumer)
{
	tdav_audiounit_instance_t* inst = (tdav_audiounit_instance_t*)self;
	if(!inst || !inst->audioUnit){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}
	
	tsk_safeobj_lock(inst);
	
	if(consumer){
		inst->prepared.consumer = tsk_true;
	}
	else {
		inst->prepared.producer = tsk_true;
	}
	
	OSStatus status;
	
	// For iOS we are using full-duplex AudioUnit and we wait for both consumer and producer to be prepared
#if TARGET_OS_IPHONE
	if(inst->prepared.consumer && inst->prepared.producer)
#endif
	{
		status = AudioUnitInitialize(inst->audioUnit);
		if(status != noErr){
			TSK_DEBUG_ERROR("AudioUnitInitialize failed with status =%ld", (signed long)status);
			tsk_safeobj_unlock(inst);
			return -2;
		}
	}	
	
	tsk_safeobj_unlock(inst);
	return 0;
}
예제 #2
0
/* get data drom the jitter buffer (consumers should always have ptime of 20ms) */
tsk_size_t tdav_consumer_video_get(tdav_consumer_video_t* self, void* out_data, tsk_size_t out_size)
{
	tsk_size_t ret_size = 0;
	if(!self && self->jitterbuffer){
		TSK_DEBUG_ERROR("Invalid parameter");
		return 0;
	}

	tsk_safeobj_lock(self);

	if(!TMEDIA_JITTER_BUFFER(self->jitterbuffer)->opened){
		int ret;
		uint32_t frame_duration = (1000 / TMEDIA_CONSUMER(self)->video.fps);
		static uint32_t rate = 90000;
		static uint32_t channles = 1;
		if((ret = tmedia_jitterbuffer_open(TMEDIA_JITTER_BUFFER(self->jitterbuffer), frame_duration, rate, channles))){
			TSK_DEBUG_ERROR("Failed to open jitterbuffer (%d)", ret);
			tsk_safeobj_unlock(self);
			return 0;
		}
	}
	ret_size = tmedia_jitterbuffer_get(TMEDIA_JITTER_BUFFER(self->jitterbuffer), out_data, out_size);

	tsk_safeobj_unlock(self);
	

	

	return ret_size;
}
예제 #3
0
int tdav_consumer_video_put(tdav_consumer_video_t* self, const void* data, tsk_size_t data_size, const tsk_object_t* proto_hdr)
{
	const trtp_rtp_header_t* rtp_hdr = TRTP_RTP_HEADER(proto_hdr);
	int ret;

	if(!self || !data || !self->jitterbuffer || !rtp_hdr){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}

	tsk_safeobj_lock(self);

	if(!TMEDIA_JITTER_BUFFER(self->jitterbuffer)->opened){
		uint32_t frame_duration = (1000 / TMEDIA_CONSUMER(self)->video.fps);
		static uint32_t rate = 90000;
		static uint32_t channels = 1;
		if((ret = tmedia_jitterbuffer_open(TMEDIA_JITTER_BUFFER(self->jitterbuffer), frame_duration, rate, channels))){
			TSK_DEBUG_ERROR("Failed to open jitterbuffer (%d)", ret);
			tsk_safeobj_unlock(self);
			return ret;
		}
	}
	ret = tmedia_jitterbuffer_put(TMEDIA_JITTER_BUFFER(self->jitterbuffer), (void*)data, data_size, proto_hdr);

	tsk_safeobj_unlock(self);

	return ret;
}
예제 #4
0
/* put data (bytes not shorts) into the jitter buffer (consumers always have ptime of 20ms) */
int tdav_consumer_audio_put(tdav_consumer_audio_t* self, const void* data, tsk_size_t data_size, const tsk_object_t* proto_hdr)
{
	int ret;

	if(!self || !data || !self->jitterbuffer){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}

	tsk_safeobj_lock(self);

	if(!TMEDIA_JITTER_BUFFER(self->jitterbuffer)->opened){
		uint32_t rate = TMEDIA_CONSUMER(self)->audio.out.rate ? TMEDIA_CONSUMER(self)->audio.out.rate : TMEDIA_CONSUMER(self)->audio.in.rate;
		uint32_t channels = TMEDIA_CONSUMER(self)->audio.out.channels ? TMEDIA_CONSUMER(self)->audio.out.channels : tmedia_defaults_get_audio_channels_playback();
		if((ret = tmedia_jitterbuffer_open(self->jitterbuffer, TMEDIA_CONSUMER(self)->audio.ptime, rate, channels))){
			TSK_DEBUG_ERROR("Failed to open jitterbuffer (%d)", ret);
			tsk_safeobj_unlock(self);
			return ret;
		}
	}
	
	ret = tmedia_jitterbuffer_put(self->jitterbuffer, (void*)data, data_size, proto_hdr);

	tsk_safeobj_unlock(self);

	return ret;
}
예제 #5
0
/* get data from the jitter buffer (consumers should always have ptime of 20ms) */
tsk_size_t tdav_consumer_audio_get(tdav_consumer_audio_t* self, void* out_data, tsk_size_t out_size)
{
	tsk_size_t ret_size = 0;
	if(!self || !self->jitterbuffer){
		TSK_DEBUG_ERROR("Invalid parameter");
		return 0;
	}

	tsk_safeobj_lock(self);

	if(!TMEDIA_JITTER_BUFFER(self->jitterbuffer)->opened){
		int ret;
		uint32_t frame_duration = TMEDIA_CONSUMER(self)->audio.ptime;
		uint32_t rate = TMEDIA_CONSUMER(self)->audio.out.rate ? TMEDIA_CONSUMER(self)->audio.out.rate : TMEDIA_CONSUMER(self)->audio.in.rate;
		uint32_t channels = TMEDIA_CONSUMER(self)->audio.out.channels ? TMEDIA_CONSUMER(self)->audio.out.channels : tmedia_defaults_get_audio_channels_playback();
		if((ret = tmedia_jitterbuffer_open(TMEDIA_JITTER_BUFFER(self->jitterbuffer), frame_duration, rate, channels))){
			TSK_DEBUG_ERROR("Failed to open jitterbuffer (%d)", ret);
			tsk_safeobj_unlock(self);
			return 0;
		}
	}
	ret_size = tmedia_jitterbuffer_get(TMEDIA_JITTER_BUFFER(self->jitterbuffer), out_data, out_size);

	tsk_safeobj_unlock(self);	

	// denoiser
	if(self->denoise && self->denoise->opened && (self->denoise->echo_supp_enabled || self->denoise->noise_supp_enabled)){
		if(self->denoise->echo_supp_enabled){
			// Echo process last frame 
			if(self->denoise->last_frame && self->denoise->last_frame->size){
				tmedia_denoise_echo_playback(self->denoise, self->denoise->last_frame->data, self->denoise->last_frame->size);
			}
			if(ret_size){
				// save
				tsk_buffer_copy(self->denoise->last_frame, 0, out_data, ret_size);
			}
		}

#if 1 // suppress noise if not supported by remote party's encoder
		// suppress noise
		if(self->denoise->noise_supp_enabled){
			tmedia_denoise_process_playback(self->denoise, out_data, out_size);
		}
#endif
	}

	return ret_size;
}
예제 #6
0
/**Acknowledge a Ghost state.
*/
void tcomp_deflatedata_ackGhost(tcomp_compressordata_t *data, const tcomp_buffer_handle_t *stateid)
{
	tcomp_deflatedata_t *deflatedata = data;
	if(!deflatedata){
		TSK_DEBUG_ERROR("NULL defalte data.");
		return;
	}

	tsk_safeobj_lock(deflatedata);
	
#if USE_ONLY_ACKED_STATES
	if(deflatedata->ghostState){
		/* Update ghost */
		if(tcomp_buffer_startsWith(deflatedata->ghostState->identifier, stateid)){
			/* END() + COPY() */
			tcomp_deflateStream_end(&(deflatedata->stream_acked));
			tcomp_deflateStream_copy(&(deflatedata->stream_acked), &(deflatedata->stream_1));
			deflatedata->stream_acked.stateful = 1;
			deflatedata->stream_acked.dataWaitingAck = 0;
		}
	}
#endif

	tsk_safeobj_unlock(deflatedata);
}
예제 #7
0
static void* TSK_STDCALL _tdav_consumer_oss_playback_thread(void *param)
{
	tdav_consumer_oss_t*  p_oss = (tdav_consumer_oss_t*)param;
	int err;
	void* p_buffer = ((p_oss->n_bits_per_sample == 8) ? (void*)p_oss->p_buff16_ptr: (void*)p_oss->p_buff_ptr);
	tsk_size_t n_buffer_in_bytes = (p_oss->n_bits_per_sample == 8) ?  p_oss->n_buff16_size_in_bytes :  p_oss->n_buff_size_in_bytes;
	tsk_size_t n_buffer_in_samples = p_oss->n_buff_size_in_samples;

	const void* _p_buffer;
	tsk_size_t _n_buffer_in_bytes;

	OSS_DEBUG_INFO("__playback_thread -- START");

	tsk_thread_set_priority_2(TSK_THREAD_PRIORITY_TIME_CRITICAL);
	
	while (p_oss->b_started) {
		tsk_safeobj_lock(p_oss);
		err = tdav_consumer_audio_get(TDAV_CONSUMER_AUDIO(p_oss), p_buffer, n_buffer_in_bytes); // requires 16bits, thread-safe
		if (err >= 0) {
			_p_buffer = p_buffer;
			_n_buffer_in_bytes = n_buffer_in_bytes;
			if (err < n_buffer_in_bytes) {
				memset(((uint8_t*)p_buffer) + err, 0, (n_buffer_in_bytes - err));
			}
			if (p_oss->n_bits_per_sample == 8) {
				__oss_from_16bits_to_8bits(p_buffer, p_oss->p_buff_ptr, n_buffer_in_samples);
				_p_buffer = p_oss->p_buff_ptr;
				_n_buffer_in_bytes >>= 1; 
			}
			if ((err = write(p_oss->fd, _p_buffer, _n_buffer_in_bytes)) != _n_buffer_in_bytes) {
				OSS_DEBUG_ERROR ("Failed to read data from audio interface failed (%d -> %s)", err , strerror(errno));
				tsk_safeobj_unlock(p_oss);
				goto bail;
			}
		}
예제 #8
0
static int _tdav_producer_video_v4l2_stop(tmedia_producer_t* p_self)
{
    tdav_producer_video_v4l2_t* p_v4l2 = (tdav_producer_video_v4l2_t*)p_self;

    if (!p_v4l2) {
        V4L2_DEBUG_ERROR("Invalid parameter");
        return -1;
    }

    tsk_safeobj_lock(p_v4l2);

    if (!p_v4l2->b_started) {
        V4L2_DEBUG_INFO("Already stopped");
        goto bail;
    }

    if (p_v4l2->p_timer_mgr) {
        tsk_timer_manager_stop(p_v4l2->p_timer_mgr);
    }

    // next start will be called after prepare()
    _v4l2_unprepare(p_v4l2); // stop() then unprepare()

    p_v4l2->b_started = tsk_false;
    p_v4l2->b_paused = tsk_false;
    p_v4l2->b_prepared = tsk_false;

bail:
    tsk_safeobj_unlock(p_v4l2);
    V4L2_DEBUG_INFO("Stopped");

    return 0;
}
예제 #9
0
/*== Add new socket ==*/
int addSocket(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport, tsk_bool_t take_ownership, tsk_bool_t is_client)
{
	transport_context_t *context = transport?transport->context:0;
	if(context){
		transport_socket_xt *sock = tsk_calloc(1, sizeof(transport_socket_xt));
		sock->fd = fd;
		sock->type = type;
		sock->owner = take_ownership;

		if((TNET_SOCKET_TYPE_IS_TLS(sock->type) || TNET_SOCKET_TYPE_IS_WSS(sock->type)) && transport->tls.enabled){
#if HAVE_OPENSSL
			sock->tlshandle = tnet_tls_socket_create(sock->fd, is_client ? transport->tls.ctx_client : transport->tls.ctx_server);       
#endif
		}
		
		tsk_safeobj_lock(context);
		
		context->ufds[context->count].fd = fd;
		context->ufds[context->count].events = (fd == context->pipeR) ? TNET_POLLIN : context->events;
		context->ufds[context->count].revents = 0;
		context->sockets[context->count] = sock;
		
		context->count++;
		
		tsk_safeobj_unlock(context);
		
		TSK_DEBUG_INFO("Socket added: fd=%d, tail.count=%d", fd, context->count);
		
		return 0;
	}
	else{
		TSK_DEBUG_ERROR("Context is Null.");
		return -1;
	}
}
/*== Add new socket ==*/
int addSocket(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport, tsk_bool_t take_ownership, tsk_bool_t is_client)
{
	transport_context_t *context = transport?transport->context:0;
	if (context) {
		transport_socket_t *sock = tsk_calloc(1, sizeof(transport_socket_t));
		sock->fd = fd;
		sock->type = type;
		sock->owner = take_ownership;

        // TODO: Find out how to specify client certificate
		//if (TNET_SOCKET_TYPE_IS_TLS(sock->type)) {
		//	sock->tlshandle = tnet_sockfd_set_tlsfiles(sock->fd, is_client, transport->tls.ca, transport->tls.pvk, transport->tls.pbk);
		//}
		
		tsk_safeobj_lock(context);
        
		context->sockets[context->count] = sock;
		context->count++;
		
		tsk_safeobj_unlock(context);
		
		TSK_DEBUG_INFO("Socket added");
		
		return 0;
	}
	else{
		TSK_DEBUG_ERROR("Context is Null.");
		return -1;
	}
}
예제 #11
0
static int _tdav_producer_video_v4l2_timer_cb(const void* arg, tsk_timer_id_t timer_id)
{
    tdav_producer_video_v4l2_t* p_v4l2 = (tdav_producer_video_v4l2_t*)arg;
    int ret = 0;

    tsk_safeobj_lock(p_v4l2);

    if (p_v4l2->id_timer_grab == timer_id) {
        if (ret = _tdav_producer_video_v4l2_grab(p_v4l2)) {
            // goto bail;
        }
        if (p_v4l2->b_started) {
            p_v4l2->id_timer_grab = tsk_timer_manager_schedule(p_v4l2->p_timer_mgr, p_v4l2->u_timout_grab, _tdav_producer_video_v4l2_timer_cb, p_v4l2);
            if (!TSK_TIMER_ID_IS_VALID(p_v4l2->id_timer_grab)) {
                V4L2_DEBUG_ERROR("Failed to schedule timer with timeout=%llu", p_v4l2->u_timout_grab);
                ret = -2;
                goto bail;
            }
        }
    }

bail:
    tsk_safeobj_unlock(p_v4l2);
    return ret;
}
예제 #12
0
int tnet_transport_stop(tnet_transport_t *transport)
{
    int ret;
    transport_context_t *context;

    if(!transport) {
        return -1;
    }

    context = transport->context;

    if((ret = tsk_runnable_stop(TSK_RUNNABLE(transport)))) {
        return ret;
    }

    if(context) {
        static char c = '\0';

        // signal
        tsk_safeobj_lock(context); // =>MUST
        if(tnet_transport_have_socket(transport, context->pipeR)) { // to avoid SIGPIPE=> check that there is at least one reader
            write(context->pipeW, &c, 1);
        }
        tsk_safeobj_unlock(context);
    }

    if(transport->mainThreadId[0]) {
        return tsk_thread_join(transport->mainThreadId);
    }
    else {
        /* already soppped */
        return 0;
    }
}
예제 #13
0
/*== Add new socket ==*/
static int addSocket(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport, int take_ownership, int is_client)
{
	transport_context_t *context = transport?transport->context:0;

	if(context){
		transport_socket_t *sock = tsk_calloc(1, sizeof(transport_socket_t));
		sock->fd = fd;
		sock->type = type;
		sock->owner = take_ownership ? 1 : 0;

		if(TNET_SOCKET_TYPE_IS_TLS(sock->type)){
			sock->tlshandle = tnet_sockfd_set_tlsfiles(sock->fd, is_client, transport->tls.ca, transport->tls.pvk, transport->tls.pbk);
		}
		
		tsk_safeobj_lock(context);
		context->events[context->count] = WSACreateEvent();
		context->sockets[context->count] = sock;
		
		context->count++;
		tsk_safeobj_unlock(context);

		return 0;
	}
	else{
		TSK_DEBUG_ERROR("Context is Null.");
		return -1;
	}
}
예제 #14
0
void tdav_consumer_audio_set_jitterbuffer(tdav_consumer_audio_t* self, struct tmedia_jitterbuffer_s* jitterbuffer)
{
	tsk_safeobj_lock(self);
	TSK_OBJECT_SAFE_FREE(self->jitterbuffer);
	self->jitterbuffer = (struct tmedia_jitterbuffer_s*)tsk_object_ref(jitterbuffer);
	tsk_safeobj_unlock(self);
}
예제 #15
0
/* set denioiser */
void tdav_consumer_audio_set_denoise(tdav_consumer_audio_t* self, struct tmedia_denoise_s* denoise)
{
	tsk_safeobj_lock(self);
	TSK_OBJECT_SAFE_FREE(self->denoise);
	self->denoise = (struct tmedia_denoise_s*)tsk_object_ref(denoise);
	tsk_safeobj_unlock(self);
}
예제 #16
0
static int _tdav_producer_video_v4l2_start(tmedia_producer_t* p_self)
{
    tdav_producer_video_v4l2_t* p_v4l2 = (tdav_producer_video_v4l2_t*)p_self;
    int ret = 0;

    if (!p_v4l2) {
        V4L2_DEBUG_ERROR("Invalid parameter");
        return -1;
    }

    tsk_safeobj_lock(p_v4l2);

    if (!p_v4l2->b_prepared) {
        V4L2_DEBUG_INFO("Not prepared");
        ret = -1;
        goto bail;
    }

    p_v4l2->b_paused = tsk_false;

    if (p_v4l2->b_started) {
        V4L2_DEBUG_INFO("Already started");
        goto bail;
    }

    if ((ret = tsk_timer_manager_start(p_v4l2->p_timer_mgr))) {
        goto bail;
    }

    // start()
    if ((ret = _v4l2_start(p_v4l2))) {
        goto bail;
    }

    p_v4l2->b_started = tsk_true;

    // Schedule frame grabbing
    p_v4l2->id_timer_grab = tsk_timer_manager_schedule(p_v4l2->p_timer_mgr, p_v4l2->u_timout_grab, _tdav_producer_video_v4l2_timer_cb, p_v4l2);
    if (!TSK_TIMER_ID_IS_VALID(p_v4l2->id_timer_grab)) {
        V4L2_DEBUG_ERROR("Failed to schedule timer with timeout=%llu", p_v4l2->u_timout_grab);
        ret = -2;
        goto bail;
    }

bail:
    if (ret) {
        _v4l2_stop(p_v4l2);
        p_v4l2->b_started = tsk_false;
        if (p_v4l2->p_timer_mgr) {
            tsk_timer_manager_stop(p_v4l2->p_timer_mgr);
        }
    }
    else {
        V4L2_DEBUG_INFO("Started :)");
    }
    tsk_safeobj_unlock(p_v4l2);

    return ret;
}
예제 #17
0
static int _tdav_producer_video_v4l2_grab(tdav_producer_video_v4l2_t* p_self)
{
    int ret = 0, r;
    fd_set fds;
    struct timeval tv;

    if (!p_self) {
        V4L2_DEBUG_ERROR("Invalid parameter");
        return -1;
    }

    tsk_safeobj_lock(p_self);

    if (!p_self->b_started) {
        V4L2_DEBUG_ERROR("producer not started yet");
        ret = -2;
        goto bail;
    }

    if (!TMEDIA_PRODUCER(p_self)->enc_cb.callback) {
        goto bail;
    }

    FD_ZERO(&fds);
    FD_SET(p_self->fd, &fds);

    /* Timeout. */
    tv.tv_sec = 0;
    tv.tv_usec = (p_self->id_timer_grab * 1000);
    while (tv.tv_usec >= 1000000) {
        tv.tv_usec -= 1000000;
        tv.tv_sec++;
    }

    r = select(p_self->fd + 1, &fds, NULL, NULL, &tv);

    if (-1 == r) {
        if (EINTR == errno) {
            V4L2_DEBUG_INFO("select() returned EINTR");
        }
        else {
            V4L2_DEBUG_ERROR("select() failed: %s error %d", strerror(errno), errno);
        }
        goto bail;
    }

    if (0 == r) {
        V4L2_DEBUG_INFO("select() timeout: %s error %d", strerror(errno), errno);
        goto bail;
    }
    // Grab a frame
    if ((ret = _v4l2_send_frame(p_self))) {
        goto bail;
    }
bail:
    tsk_safeobj_unlock(p_self);

    return ret;
}
void __CFWriteStreamClientCallBack(CFWriteStreamRef stream, CFStreamEventType eventType, void *clientCallBackInfo) {
    // Extract the context
    tnet_transport_t *transport = (tnet_transport_t *) clientCallBackInfo;
	transport_context_t *context = transport->context;
    
    /* lock context */
    tsk_safeobj_lock(context);
    
    // Extract the native socket
    CFDataRef data = CFWriteStreamCopyProperty(stream, kCFStreamPropertySocketNativeHandle);
    CFSocketNativeHandle fd;
    CFDataGetBytes(data, CFRangeMake(0, sizeof(CFSocketNativeHandle)), (UInt8*) &fd);
    CFRelease(data);
    transport_socket_t *sock = (transport_socket_t *) getSocket(context, fd);
    
    switch(eventType) {
        case kCFStreamEventOpenCompleted:
        {
            TSK_DEBUG_INFO("__CFWriteStreamClientCallBack --> kCFStreamEventOpenCompleted");
            
            if (TNET_SOCKET_TYPE_IS_SECURE(sock->type)) {
#if !TARGET_OS_IPHONE
                SSLContextRef sslContext = NULL;
                data = CFWriteStreamCopyProperty(stream, kCFStreamPropertySocketSSLContext);
                CFDataGetBytes(data, CFRangeMake(0, sizeof(SSLContextRef)), (UInt8*) &sslContext);
                CFRelease(data);
                
                // TODO: Set the client certificates
#endif
            }
            
            break;
        }
        case kCFStreamEventEndEncountered:
        case kCFStreamEventErrorOccurred:
        {
            // Get the error code
            CFErrorRef error = CFWriteStreamCopyError(stream);
            CFIndex index = CFErrorGetCode(error);
            CFRelease(error);
            
            TSK_DEBUG_INFO("__CFWriteStreamClientCallBack --> Error %lu", index);
            
            TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, sock->fd);
            removeSocket(sock, context);
            break;
        }
        default:
        {
            // Not Implemented
            assert(42 == 0);
            break;
        }
    }
    
    /* unlock context */
    tsk_safeobj_unlock(context);
}
/*== Remove socket ==*/
int removeSocketAtIndex(int index, transport_context_t *context)
{
	int i;
	
	tsk_safeobj_lock(context);
    
	if (index < (int)context->count) {
        transport_socket_t *sock = context->sockets[index];
        
		// Free tls context
		//TSK_OBJECT_SAFE_FREE(sock->tlshandle);
		
		// Invalidate CFSocket
        if (sock->cf_socket) {
            if (CFSocketIsValid(sock->cf_socket)) {
                CFSocketInvalidate(sock->cf_socket);
            }
            CFRelease(sock->cf_socket);
        }
		// Close and free read stream
        if (sock->cf_read_stream) {
            // TODO: Investigate if we really need to do that
            //if (CFReadStreamGetStatus(sock->cf_read_stream) == kCFStreamStatusOpen) {
            //    CFReadStreamClose(sock->cf_read_stream);
            //}
            CFRelease(sock->cf_read_stream);
        }
		// Close and free write stream
        if (sock->cf_write_stream) {
            // TODO: Investigate if we really need to do that
            //if (CFWriteStreamGetStatus(sock->cf_write_stream) == kCFStreamStatusOpen) {
            //    CFWriteStreamClose(sock->cf_write_stream);
            //}
            CFRelease(sock->cf_write_stream);
        }
        
		// Close the socket if we are the owner.
		if (sock->owner) {
			tnet_sockfd_close(&(sock->fd));
		}
        
		TSK_FREE(sock);
		
		for(i=index ; i<context->count-1; i++) {			
			context->sockets[i] = context->sockets[i+1];
		}
		
		context->sockets[context->count-1] = 0;
		context->count--;
        
		TSK_DEBUG_INFO("Socket removed");
	}
    
	tsk_safeobj_unlock(context);
	
	return 0;
}
예제 #20
0
static int _tnet_dtls_verify_cert(int preverify_ok, X509_STORE_CTX *ctx)
{
	SSL *ssl;
	tnet_dtls_socket_t* socket;

	TSK_DEBUG_INFO("_tnet_dtls_verify_cert");

	ssl = X509_STORE_CTX_get_app_data(ctx);
	socket = (tnet_dtls_socket_t*)SSL_get_app_data(ssl);
	if (!ssl || !socket){
		TSK_DEBUG_ERROR("Not expected");
		return 0;
	}
	tsk_safeobj_lock(socket);
	if (_tnet_dtls_is_fingerprint_matching(ctx->cert, &socket->remote.fp, socket->remote.hash) == tsk_false) {
		TSK_DEBUG_ERROR("Failed to match fingerprint");
		tsk_safeobj_unlock(socket);
		return 0;
	}
	tsk_safeobj_unlock(socket);
	return 1;
}
예제 #21
0
/** Reset jitterbuffer */
int tdav_consumer_video_reset(tdav_consumer_video_t* self){
	int ret;
	if(!self){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}

	tsk_safeobj_lock(self);
	ret = tmedia_jitterbuffer_reset(TMEDIA_JITTER_BUFFER(self->jitterbuffer));
	tsk_safeobj_unlock(self);

	return ret;
}
예제 #22
0
/* Remove socket */
int tnet_transport_remove_socket(const tnet_transport_handle_t *handle, tnet_fd_t *pfd)
{
    tnet_transport_t *transport = (tnet_transport_t*)handle;
    transport_context_t *context;
    int ret = -1;
    tsk_size_t i;
    tsk_bool_t found = tsk_false;
    tnet_fd_t fd = *pfd;

    TSK_DEBUG_INFO("Removing socket %d", fd);

    if(!transport) {
        TSK_DEBUG_ERROR("Invalid server handle.");
        return ret;
    }

    if(!(context = (transport_context_t*)transport->context)) {
        TSK_DEBUG_ERROR("Invalid context.");
        return -2;
    }

    tsk_safeobj_lock(context);

    for(i=0; i<context->count; i++) {
        if(context->sockets[i]->fd == fd) {
            tsk_bool_t self_ref = (&context->sockets[i]->fd == pfd);
            removeSocket(i, context); // sockets[i] will be destroyed
            found = tsk_true;
            TSK_RUNNABLE_ENQUEUE(transport, event_removed, transport->callback_data, fd);
            if(!self_ref) { // if self_ref then, pfd no longer valid after removeSocket()
                *pfd = TNET_INVALID_FD;
            }
            break;
        }
    }

    tsk_safeobj_unlock(context);

    if(found) {
        /* Signal */
        static char c = '\0';
        ret = write(context->pipeW, &c, 1);
        return (ret > 0 ? 0 : ret);
    }

    // ...

    return -1;
}
예제 #23
0
static tsk_object_t* tdav_audiounit_instance_dtor(tsk_object_t * self)
{ 
	tdav_audiounit_instance_t* inst = self;
	if(inst){
        tsk_safeobj_lock(inst);
		if(inst->audioUnit){
            AudioUnitUninitialize(inst->audioUnit);
            AudioComponentInstanceDispose(inst->audioUnit);
            inst->audioUnit = tsk_null;
		}
        tsk_safeobj_unlock(inst);
        
		tsk_safeobj_deinit(inst);
	}
	return self;
}
예제 #24
0
int tdav_audiounit_handle_stop(tdav_audiounit_handle_t* self)
{
	tdav_audiounit_instance_t* inst = (tdav_audiounit_instance_t*)self;
	OSStatus status = noErr;
	if(!inst || (inst->started && !inst->audioUnit)){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}
	
	tsk_safeobj_lock(inst);
	if(inst->started && (status = AudioOutputUnitStop(inst->audioUnit))){
		TSK_DEBUG_ERROR("AudioOutputUnitStop failed with status=%ld", (signed long)status);
	}
    inst->started = (status == noErr ? tsk_false : tsk_true);
	tsk_safeobj_unlock(inst);
	return status ? -2 : 0;
}
예제 #25
0
/*== Add new socket ==*/
static int addSocket(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport, tsk_bool_t take_ownership, tsk_bool_t is_client, tnet_tls_socket_handle_t* tlsHandle)
{
    transport_context_t *context;

    if (TNET_SOCKET_TYPE_IS_TLS(type) || TNET_SOCKET_TYPE_IS_WSS(type)) {
#if !HAVE_OPENSSL
        TSK_DEBUG_ERROR("Cannot create TLS socket: OpenSSL missing");
        return -2;
#endif
    }

    if ((context = transport ? transport->context : tsk_null)) {
        transport_socket_xt *sock = tsk_calloc(1, sizeof(transport_socket_xt));
        sock->fd = fd;
        sock->type = type;
        sock->owner = take_ownership ? 1 : 0;

        if ((TNET_SOCKET_TYPE_IS_TLS(sock->type) || TNET_SOCKET_TYPE_IS_WSS(sock->type)) && transport->tls.enabled) {
            if (tlsHandle) {
                sock->tlshandle = tsk_object_ref(tlsHandle);
            }
            else {
#if HAVE_OPENSSL
                sock->tlshandle = tnet_tls_socket_create(sock->fd, is_client ? transport->tls.ctx_client : transport->tls.ctx_server);
#endif
            }
        }

        tsk_safeobj_lock(context);
        context->events[context->count] = WSACreateEvent();
        context->sockets[context->count] = sock;

        context->count++;

        TSK_DEBUG_INFO("Transport[%s] sockets count = %u", transport->description, context->count);

        tsk_safeobj_unlock(context);

        return 0;
    }
    else {
        TSK_DEBUG_ERROR("Context is Null.");
        return -1;
    }
}
예제 #26
0
/**Updates a Ghost state.
*/
void tcomp_deflatedata_updateGhost(tcomp_deflatedata_t *deflatedata, const uint8_t *input_ptr, tsk_size_t input_size)
{
	uint32_t i;
	uint8_t *ghostvalue_ptr = 0;

#define GHOSTVALUE_AT(position) (ghostvalue_ptr + position)
		
	if(!deflatedata){
		TSK_DEBUG_ERROR("NULL defalte data.");
		return;
	}

	if(!deflatedata->ghostState){
		TSK_DEBUG_ERROR("NULL ghost state.");
		return;
	}

	tsk_safeobj_lock(deflatedata);

	ghostvalue_ptr = tcomp_buffer_getBuffer(deflatedata->ghostState->value);

#define ZBUFF_LEN	(0x0001 << deflatedata->zWindowBits)
	for(i = 0; i < input_size; i++){
#if 0
		*GHOSTVALUE_AT(GHOST_INPUT_INDEX + ghost_copy_offset) = 0x00;
#else
		*GHOSTVALUE_AT(GHOST_INPUT_INDEX + deflatedata->ghost_copy_offset) = input_ptr[i];
#endif
		deflatedata->ghost_copy_offset = (deflatedata->ghost_copy_offset + 1) % ZBUFF_LEN;
	}

	/* Update Circular Buffer Index */
	TSK_BINARY_SET_2BYTES( GHOSTVALUE_AT(GHOST_CB_END_INDEX), (DEFLATE_UDVM_CIRCULAR_START_INDEX + deflatedata->ghost_copy_offset) );
	
	/* Compute State Identifier (20 bytes) */
	tcomp_state_makeValid(deflatedata->ghostState);
	
	/*printf("GHOST\n");
	tcomp_buffer_nprint(deflatedata->ghostState->value);
	tcomp_buffer_nprint(deflatedata->ghostState->identifier);*/
	
	tsk_safeobj_unlock(deflatedata);

#undef GHOSTVALUE_AT
}
int removeSocket(transport_socket_t *value, transport_context_t *context)
{
	int i;
	
	tsk_safeobj_lock(context);
    
    for(i = 0; i < context->count; i++) {
        transport_socket_t *sock = context->sockets[i];
        if (sock == value) {
            removeSocketAtIndex(i, context);
            break;
        }
    }
    
	tsk_safeobj_unlock(context);
	
	return 0;
}
/*== Get socket ==*/
static const transport_socket_t* getSocket(transport_context_t *context, tnet_fd_t fd)
{
	tsk_size_t i;
	transport_socket_t* ret = 0;
    
	if (context) {
		tsk_safeobj_lock(context);
		for(i=0; i<context->count; i++) {
			if (context->sockets[i]->fd == fd) {
				ret = context->sockets[i];
				break;
			}
		}
		tsk_safeobj_unlock(context);
	}
	
	return ret;
}
예제 #29
0
/*== Remove socket ==*/
int removeSocket(int index, transport_context_t *context)
{
    int i;

    tsk_safeobj_lock(context);

    if(index < (int)context->count) {
        /* Close the socket if we are the owner. */
        TSK_DEBUG_INFO("Socket to remove: fd=%d, index=%d, tail.count=%d", context->sockets[index]->fd, index, (int)context->count);
        if(context->sockets[index]->owner) {
            // do not close the socket while it's being poll()ed
            // http://stackoverflow.com/questions/5039608/poll-cant-detect-event-when-socket-is-closed-locally
            if(context->polling) {
                TSK_DEBUG_INFO("RemoveSocket(fd=%d) has been requested but we are poll()ing the socket. ShutdownSocket(fd) called on the socket and we deferred the request.", context->sockets[index]->fd);
                TSK_DEBUG_INFO("ShutdownSocket(fd=%d)", context->sockets[index]->fd);
                tnet_sockfd_shutdown(context->sockets[index]->fd);
                goto done;
            }
            tnet_sockfd_close(&(context->sockets[index]->fd));
        }

        /* Free tls context */
        TSK_OBJECT_SAFE_FREE(context->sockets[index]->tlshandle);

        // Free socket
        TSK_FREE(context->sockets[index]);

        for(i=index ; i<context->count-1; i++) {
            context->sockets[i] = context->sockets[i+1];
            context->ufds[i] = context->ufds[i+1];
        }

        context->sockets[context->count-1] = tsk_null;
        context->ufds[context->count-1].fd = TNET_INVALID_FD;
        context->ufds[context->count-1].events = 0;
        context->ufds[context->count-1].revents = 0;

        context->count--;
    }
done:
    tsk_safeobj_unlock(context);

    return 0;
}
예제 #30
0
/*== Add new socket ==*/
int addSocket(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport, tsk_bool_t take_ownership, tsk_bool_t is_client, tnet_tls_socket_handle_t* tlsHandle)
{
    transport_context_t *context = transport?transport->context:0;
    if(context) {
        transport_socket_xt *sock = tsk_calloc(1, sizeof(transport_socket_xt));
        sock->fd = fd;
        sock->type = type;
        sock->owner = take_ownership;

        if((TNET_SOCKET_TYPE_IS_TLS(sock->type) || TNET_SOCKET_TYPE_IS_WSS(sock->type)) && transport->tls.enabled) {
            if(tlsHandle) {
                sock->tlshandle = tsk_object_ref(tlsHandle);
            }
            else {
#if HAVE_OPENSSL
                sock->tlshandle = tnet_tls_socket_create(sock->fd, is_client ? transport->tls.ctx_client : transport->tls.ctx_server);
#endif
            }
        }

        tsk_safeobj_lock(context);

        context->ufds[context->count].fd = fd;
        context->ufds[context->count].events = (fd == context->pipeR) ? TNET_POLLIN : (TNET_POLLIN | TNET_POLLNVAL | TNET_POLLERR);
        if(TNET_SOCKET_TYPE_IS_STREAM(sock->type) && fd != context->pipeR) {
            context->ufds[context->count].events |= TNET_POLLOUT; // emulate WinSock2 FD_CONNECT event
        }
        context->ufds[context->count].revents = 0;
        context->sockets[context->count] = sock;

        context->count++;

        tsk_safeobj_unlock(context);

        TSK_DEBUG_INFO("Socket added[%s]: fd=%d, tail.count=%d", transport->description, fd, (int)context->count);

        return 0;
    }
    else {
        TSK_DEBUG_ERROR("Context is Null.");
        return -1;
    }
}