Example #1
0
static THREADFUNCDECL(main_proc_thread_func)
{
	const int sleep_ms = 5;
	const int counts_per_second = 1000 / sleep_ms;
	static int refresh_registration_count = 0;
	static int audio_error_count = 0;
	static int audio_error_state = 0;

	THREADFUNCRET(ret);

	/* Increase Priority */
	iaxci_prioboostbegin();

	while ( !main_proc_thread_flag )
	{
		get_iaxc_lock();

		service_network();

		if ( !test_mode &&
				(!audio_error_state ||
				 audio_error_count++ % counts_per_second == 0) )
		{
			/* There are cases when service audio fails such
			 * as when there is no audio devices present in
			 * the system. In these cases, only call
			 * service_audio() once per second until it
			 * succeeds.
			 */
			if ( (audio_error_state = service_audio()) )
			{
				iaxci_usermsg(IAXC_NOTICE,
						"failed to service audio");

				if ( audio_error_count / counts_per_second == 5 )
					iaxci_usermsg(IAXC_TEXT_TYPE_FATALERROR,
							"cannot open audio device"
							" after several tries");
			}
		}

		// Check registration refresh once a second
		if ( refresh_registration_count++ > counts_per_second )
		{
			iaxc_refresh_registrations();
			refresh_registration_count = 0;
		}

		put_iaxc_lock();

		iaxc_millisleep(sleep_ms);
	}

	/* Decrease priority */
	iaxci_prioboostend();

	main_proc_thread_flag = -1;

	return ret;
}
Example #2
0
EXPORT void iaxc_dump_all_calls(void)
{
	int callNo;
	get_iaxc_lock();
	for ( callNo = 0; callNo < max_calls; callNo++ )
		iaxc_dump_one_call(callNo);
	put_iaxc_lock();
}
Example #3
0
EXPORT int iaxc_unregister( int id )
{
	int count = 0;
	get_iaxc_lock();
	count = iaxc_remove_registration_by_id(id);
	put_iaxc_lock();
	return count;
}
Example #4
0
EXPORT void iaxc_dump_call_number( int callNo )
{
	if ( ( callNo >= 0 ) && ( callNo < max_calls ) )
	{
		get_iaxc_lock();
		iaxc_dump_one_call(callNo);
		put_iaxc_lock();
	}
}
Example #5
0
EXPORT void iaxc_dump_call(void)
{
	if ( selected_call >= 0 )
	{
		get_iaxc_lock();
		iaxc_dump_one_call(selected_call);
		put_iaxc_lock();
	}
}
Example #6
0
EXPORT void iaxc_send_url(const char * url, int link)
{
	if ( selected_call >= 0 )
	{
		get_iaxc_lock();
		if ( calls[selected_call].state & IAXC_CALL_STATE_ACTIVE )
			iax_send_url(calls[selected_call].session, url, link);
		put_iaxc_lock();
	}
}
Example #7
0
EXPORT void iaxc_send_text_call(int callNo, const char * text)
{
	if ( callNo < 0 || !(calls[callNo].state & IAXC_CALL_STATE_ACTIVE) )
		return;

	get_iaxc_lock();
	if ( calls[callNo].state & IAXC_CALL_STATE_ACTIVE )
		iax_send_text(calls[callNo].session, text);
	put_iaxc_lock();
}
Example #8
0
EXPORT void iaxc_send_text(const char * text)
{
	if ( selected_call >= 0 )
	{
		get_iaxc_lock();
		if ( calls[selected_call].state & IAXC_CALL_STATE_ACTIVE )
			iax_send_text(calls[selected_call].session, text);
		put_iaxc_lock();
	}
}
Example #9
0
EXPORT void iaxc_send_dtmf(char digit)
{
	if ( selected_call >= 0 )
	{
		get_iaxc_lock();
		if ( calls[selected_call].state & IAXC_CALL_STATE_ACTIVE )
			iax_send_dtmf(calls[selected_call].session,digit);
		put_iaxc_lock();
	}
}
Example #10
0
EXPORT void iaxc_reject_call_number( int callNo )
{
	if ( ( callNo >= 0 ) && ( callNo < max_calls ) )
	{
		get_iaxc_lock();
		iax_reject(calls[callNo].session, "Call rejected manually.");
		iaxc_clear_call(callNo);
		put_iaxc_lock();
	}
}
Example #11
0
EXPORT void iaxc_send_text_call(int callNo, const char * text)
{
	if ( callNo >= 0 && callNo < max_calls )
	{
		get_iaxc_lock();
		if ( calls[callNo].state & IAXC_CALL_STATE_ACTIVE )
			iax_send_text(calls[callNo].session, text);
		put_iaxc_lock();
	}
}
Example #12
0
EXPORT int iaxc_audio_devices_set(int input, int output, int ring)
{
	int ret;

	if ( test_mode )
		return 0;

	get_iaxc_lock();
	ret = audio_driver.select_devices(&audio_driver, input, output, ring);
	put_iaxc_lock();
	return ret;
}
Example #13
0
EXPORT int iaxc_stop_sound(int id)
{
	int ret;

	if ( test_mode )
		return 0;

	get_iaxc_lock();
	ret = audio_driver.stop_sound(id);
	put_iaxc_lock();
	return ret;
}
Example #14
0
EXPORT int iaxc_play_sound(struct iaxc_sound *s, int ring)
{
	int ret;

	if ( test_mode )
		return 0;

	get_iaxc_lock();
	ret = audio_driver.play_sound(s,ring);
	put_iaxc_lock();
	return ret;
}
Example #15
0
EXPORT void iaxc_shutdown()
{
	iaxc_dump_all_calls();

	get_iaxc_lock();

	if ( !test_mode )
	{
		audio_driver.destroy(&audio_driver);
		audio_destroy();
#ifdef USE_VIDEO
		video_destroy();
#endif
	}
	
	/* destroy enocders and decoders for all existing calls */
	if ( calls ) 
	{
                int i;
		for ( i=0 ; i<max_calls ; i++ ) 
		{
			if ( calls[i].encoder )
				calls[i].encoder->destroy(calls[i].encoder);
			if ( calls[i].decoder )
				calls[i].decoder->destroy(calls[i].decoder);
			if ( calls[i].vencoder )
				calls[i].vencoder->destroy(calls[i].vencoder);
			if ( calls[i].vdecoder )
				calls[i].vdecoder->destroy(calls[i].vdecoder);
                }
		free(calls);
		calls = NULL;
	}
	put_iaxc_lock();
#ifdef WIN32
	closesocket(iax_get_fd()); //fd:
#endif

	free(calls);

	MUTEXDESTROY(&event_queue_lock);
	MUTEXDESTROY(&iaxc_lock);
}
Example #16
0
EXPORT int iaxc_register_ex(const char * user, const char * pass, const char * host, int refresh)
{
	struct iaxc_registration *newreg;

	newreg = (struct iaxc_registration *)malloc(sizeof (struct iaxc_registration));
	if ( !newreg )
	{
		iaxci_usermsg(IAXC_ERROR, "Can't make new registration");
		return -1;
	}

	get_iaxc_lock();
	newreg->session = iax_session_new();
	if ( !newreg->session )
	{
		iaxci_usermsg(IAXC_ERROR, "Can't make new registration session");
		put_iaxc_lock();
		return -1;
	}

	newreg->last = iax_tvnow();
	newreg->refresh = refresh;  

	strncpy(newreg->host, host, 256);
	strncpy(newreg->user, user, 256);
	strncpy(newreg->pass, pass, 256);

	/* send out the initial registration with refresh seconds */
	iax_register(newreg->session, host, user, pass, refresh);

	/* add it to the list; */
	newreg->id = ++next_registration_id;
	newreg->next = registrations;
	registrations = newreg;

	put_iaxc_lock();
	return newreg->id;
}
Example #17
0
static THREADFUNCDECL(main_proc_thread_func)
{
	static int refresh_registration_count = 0;

	THREADFUNCRET(ret);

	/* Increase Priority */
	iaxci_prioboostbegin();

	while ( !main_proc_thread_flag )
	{
		get_iaxc_lock();

		service_network();
		if ( !test_mode )
			service_audio();

		// Check registration refresh once a second
		if ( refresh_registration_count++ > 1000/LOOP_SLEEP )
		{
			iaxc_refresh_registrations();
			refresh_registration_count = 0;
		}

		put_iaxc_lock();

		iaxc_millisleep(LOOP_SLEEP);
	}

	/* Decrease priority */
	iaxci_prioboostend();

	main_proc_thread_flag = -1;

	return ret;
}
Example #18
0
EXPORT int iaxc_call_ex(const char *num, const char* callerid_name, const char* callerid_number, int video)
{
	int video_format_capability = 0;
	int video_format_preferred = 0;
	int callNo = -1;
	struct iax_session *newsession;
	char *ext = strstr(num, "/");

	get_iaxc_lock();

	// if no call is selected, get a new appearance
	if ( selected_call < 0 )
	{
		callNo = iaxc_first_free_call();
	} else
	{
		// use selected call if not active, otherwise, get a new appearance
		if ( calls[selected_call].state & IAXC_CALL_STATE_ACTIVE )
		{
			callNo = iaxc_first_free_call();
		} else
		{
			callNo = selected_call;
		}
	}

	if ( callNo < 0 )
	{
		iaxci_usermsg(IAXC_STATUS, "No free call appearances");
		goto iaxc_call_bail;
	}

	newsession = iax_session_new();
	if ( !newsession )
	{
		iaxci_usermsg(IAXC_ERROR, "Can't make new session");
		goto iaxc_call_bail;
	}

	calls[callNo].session = newsession;

	codec_destroy( callNo );

	/* When the ACCEPT comes back from the other-end, these formats
	 * are set. Whether the format is set or not determines whether
	 * we are in the Linked state (see the iax2 rfc).
	 * These will have already been cleared by iaxc_clear_call(),
	 * but we reset them anyway just to be pedantic.
	 */
	calls[callNo].format = 0;
	calls[callNo].vformat = 0;

	if ( ext )
	{
		strncpy(calls[callNo].remote_name, num, IAXC_EVENT_BUFSIZ);
		strncpy(calls[callNo].remote,    ++ext, IAXC_EVENT_BUFSIZ);
	} else
	{
		strncpy(calls[callNo].remote_name, num, IAXC_EVENT_BUFSIZ);
		strncpy(calls[callNo].remote,      "" , IAXC_EVENT_BUFSIZ);
	}

	if ( callerid_number != NULL )
		strncpy(calls[callNo].callerid_number, callerid_number, IAXC_EVENT_BUFSIZ);

	if ( callerid_name != NULL )
		strncpy(calls[callNo].callerid_name, callerid_name, IAXC_EVENT_BUFSIZ);

	strncpy(calls[callNo].local        , calls[callNo].callerid_name, IAXC_EVENT_BUFSIZ);
	strncpy(calls[callNo].local_context, "default", IAXC_EVENT_BUFSIZ);

	calls[callNo].state = IAXC_CALL_STATE_OUTGOING;

	/* reset activity and ping "timers" */
	iaxc_note_activity(callNo);
	calls[callNo].last_ping = calls[callNo].last_activity;

#ifdef USE_VIDEO
	if ( video )
		iaxc_video_format_get_cap(&video_format_preferred, &video_format_capability);
#endif

	iaxci_usermsg(IAXC_NOTICE, "Originating an %s call",
			video_format_preferred ? "audio+video" : "audio only");
	iax_call(calls[callNo].session, calls[callNo].callerid_number,
			calls[callNo].callerid_name, num, NULL, 0,
			audio_format_preferred | video_format_preferred,
			audio_format_capability | video_format_capability);

	// does state stuff also
	iaxc_select_call(callNo);

iaxc_call_bail:
	put_iaxc_lock();

	return callNo;
}
Example #19
0
EXPORT int iaxc_call_ex(const char *num, const char* callerid_name, const char* callerid_number, int video)
{
	int video_format_capability = 0;
	int video_format_preferred = 0;
	int callNo = -1;
	struct iax_session *newsession;
	char *ext = strstr(num, "/");

	get_iaxc_lock();

	// if no call is selected, get a new appearance
	if ( selected_call < 0 )
	{
		callNo = iaxc_first_free_call();
	} else
	{
		// use selected call if not active, otherwise, get a new appearance
		if ( calls[selected_call].state  & IAXC_CALL_STATE_ACTIVE )
		{
			callNo = iaxc_first_free_call();
		} else
		{
			callNo = selected_call;
		}
	}

	if ( callNo < 0 )
	{
		iaxci_usermsg(IAXC_STATUS, "No free call appearances");
		goto iaxc_call_bail;
	}

	newsession = iax_session_new();
	if ( !newsession )
	{
		iaxci_usermsg(IAXC_ERROR, "Can't make new session");
		goto iaxc_call_bail;
	}

	calls[callNo].session = newsession;

	codec_destroy( callNo );

	if ( ext )
	{
		strncpy(calls[callNo].remote_name, num, IAXC_EVENT_BUFSIZ);
		strncpy(calls[callNo].remote,    ++ext, IAXC_EVENT_BUFSIZ);
	} else
	{
		strncpy(calls[callNo].remote_name, num, IAXC_EVENT_BUFSIZ);
		strncpy(calls[callNo].remote,      "" , IAXC_EVENT_BUFSIZ);
	}

	if ( callerid_number != NULL )
		strncpy(calls[callNo].callerid_number, callerid_number, IAXC_EVENT_BUFSIZ);

	if ( callerid_name != NULL )
		strncpy(calls[callNo].callerid_name, callerid_name, IAXC_EVENT_BUFSIZ);

	strncpy(calls[callNo].local        , calls[callNo].callerid_name, IAXC_EVENT_BUFSIZ);
	strncpy(calls[callNo].local_context, "default", IAXC_EVENT_BUFSIZ);

	calls[callNo].state = IAXC_CALL_STATE_ACTIVE | IAXC_CALL_STATE_OUTGOING;

	/* reset activity and ping "timers" */
	iaxc_note_activity(callNo);
	calls[callNo].last_ping = calls[callNo].last_activity;

#ifdef USE_VIDEO
	if ( video )
		iaxc_video_format_get_cap(&video_format_preferred, &video_format_capability);
#endif

	iaxci_usermsg(IAXC_NOTICE, "Originating an %s call",
			video_format_preferred ? "audio+video" : "audio only");
	iax_call(calls[callNo].session, calls[callNo].callerid_number,
			calls[callNo].callerid_name, num, NULL, 0,
			audio_format_preferred | video_format_preferred,
			audio_format_capability | video_format_capability);

	// does state stuff also
	iaxc_select_call(callNo);

iaxc_call_bail:
	put_iaxc_lock();

	return callNo;
}