コード例 #1
0
ファイル: iaxclient_lib.c プロジェクト: dochong/iaxclient
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;
}
コード例 #2
0
ファイル: iaxclient_lib.c プロジェクト: dochong/iaxclient
static void iaxc_handle_connect(struct iax_event * e)
{
#ifdef USE_VIDEO
	int video_format_capability;
	int video_format_preferred;
#endif
	int video_format = 0;
	int format = 0;
	int callno;

	callno = iaxc_first_free_call();

	if ( callno < 0 )
	{
		iaxci_usermsg(IAXC_STATUS,
				"%i \n Incoming Call, but no appearances",
				callno);
		// XXX Reject this call!, or just ignore?
		//iax_reject(e->session, "Too many calls, we're busy!");
		iax_accept(e->session, audio_format_preferred & e->ies.capability);
		iax_busy(e->session);
		return;
	}

	/* negotiate codec */
	/* first, try _their_ preferred format */
	format = audio_format_capability & e->ies.format;
	if ( !format )
	{
		/* then, try our preferred format */
		format = audio_format_preferred & e->ies.capability;
	}

	if ( !format )
	{
		/* finally, see if we have one in common */
		format = audio_format_capability & e->ies.capability;

		/* now choose amongst these, if we got one */
		if ( format )
		{
			format = iaxc_choose_codec(format);
		}
	}

	if ( !format )
	{
		iax_reject(e->session, "Could not negotiate common codec");
		return;
	}

#ifdef USE_VIDEO
	iaxc_video_format_get_cap(&video_format_preferred,
			&video_format_capability);

	/* first, see if they even want video */
	video_format = (e->ies.format & IAXC_VIDEO_FORMAT_MASK);

	if ( video_format )
	{
		/* next, try _their_ preferred format */
		video_format &= video_format_capability;

		if ( !video_format )
		{
			/* then, try our preferred format */
			video_format = video_format_preferred &
				(e->ies.capability & IAXC_VIDEO_FORMAT_MASK);
		}

		if ( !video_format )
		{
			/* finally, see if we have one in common */
			video_format = video_format_capability &
				(e->ies.capability & IAXC_VIDEO_FORMAT_MASK);

			/* now choose amongst these, if we got one */
			if ( video_format )
			{
				video_format = iaxc_choose_codec(video_format);
			}
		}

		/* All video negotiations failed, then warn */
		if ( !video_format )
		{
			iaxci_usermsg(IAXC_NOTICE,
					"Notice: could not negotiate common video codec");
			iaxci_usermsg(IAXC_NOTICE,
					"Notice: switching to audio-only call");
		}
	}
#endif	/* USE_VIDEO */

	calls[callno].vformat = video_format;
	calls[callno].format = format;

	if ( e->ies.called_number )
		strncpy(calls[callno].local, e->ies.called_number,
				IAXC_EVENT_BUFSIZ);
	else
		strncpy(calls[callno].local, "unknown",
				IAXC_EVENT_BUFSIZ);

	if ( e->ies.called_context )
		strncpy(calls[callno].local_context, e->ies.called_context,
				IAXC_EVENT_BUFSIZ);
	else
		strncpy(calls[callno].local_context, "",
				IAXC_EVENT_BUFSIZ);

	if ( e->ies.calling_number )
		strncpy(calls[callno].remote, e->ies.calling_number,
				IAXC_EVENT_BUFSIZ);
	else
		strncpy(calls[callno].remote, "unknown",
				IAXC_EVENT_BUFSIZ);

	if ( e->ies.calling_name )
		strncpy(calls[callno].remote_name, e->ies.calling_name,
				IAXC_EVENT_BUFSIZ);
	else
		strncpy(calls[callno].remote_name, "unknown",
				IAXC_EVENT_BUFSIZ);

	iaxc_note_activity(callno);
	iaxci_usermsg(IAXC_STATUS, "Call from (%s)", calls[callno].remote);

	codec_destroy( callno );

	calls[callno].session = e->session;
	calls[callno].state = IAXC_CALL_STATE_ACTIVE|IAXC_CALL_STATE_RINGING;

	iax_accept(calls[callno].session, format | video_format);
	iax_ring_announce(calls[callno].session);

	iaxci_do_state_callback(callno);

	iaxci_usermsg(IAXC_STATUS, "Incoming call on line %d", callno);
}
コード例 #3
0
ファイル: iaxclient_lib.c プロジェクト: zlargon/iaxclient
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;
}