Beispiel #1
0
void IAXVoIPLink::iaxHandlePrecallEvent(iax_event* event)
{
    IAXCall *call;
    std::string id;
    int format;

    switch (event->etype) {
        case IAX_EVENT_CONNECT:
            id = Manager::instance().getNewCallID();

            call = new IAXCall(id, Call::INCOMING);
            call->session = event->session;
            call->setConnectionState(Call::PROGRESSING);

            if (event->ies.calling_number)
                call->setPeerNumber(event->ies.calling_number);

            if (event->ies.calling_name)
                call->setDisplayName(std::string(event->ies.calling_name));

            // if peerNumber exist append it to the name string
            call->initRecFilename(std::string(event->ies.calling_number));
            Manager::instance().incomingCall(*call, accountID_);

            format = call->getFirstMatchingFormat(event->ies.format, accountID_);

            if (!format)
                format = call->getFirstMatchingFormat(event->ies.capability, accountID_);

            iax_accept(event->session, format);
            iax_ring_announce(event->session);
            addCall(call);
            call->format = format;

            break;

        case IAX_EVENT_HANGUP:
            id = iaxFindCallBySession(event->session)->getCallId();
            Manager::instance().peerHungupCall(id);
            removeCall(id);
            break;

        case IAX_EVENT_TIMEOUT: // timeout for an unknown session
        case IAX_IE_MSGCOUNT:
        case IAX_EVENT_REGACK:
        case IAX_EVENT_REGREJ:
        case IAX_EVENT_REGREQ:
            // Received when someone wants to register to us!?!
            // Asterisk receives and answers to that, not us, we're a phone.
        default:
            break;
    }
}
Beispiel #2
0
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);
}
Beispiel #3
0
void
do_iax_event(FILE *f) {
	int sessions = 0;
	struct iax_event *e = 0;
	struct peer *peer;

	while ( (e = iax_get_event(0))) {
		peer = find_peer(e->session);
		if(peer) {
			handle_event(f, e, peer);
		} else if (e->session == registry) {
			fprintf(stderr, "Registration complete: %s (%d)\n",
				(e->event.regreply.status == IAX_REG_SUCCESS) ? "Success" : "Failed",
				e->event.regreply.status);
			registry = NULL;
		} else {
			if(e->etype != IAX_EVENT_CONNECT) {
				fprintf(stderr, "Huh? This is an event for a non-existant session?\n");
				continue;
			}
			sessions++;

			if(sessions >= MAX_SESSIONS) {
				fprintf(f, "Missed a call... too many sessions open.\n");
			}


			if(e->event.connect.callerid && e->event.connect.dnid)
				fprintf(f, "Call from '%s' for '%s'", e->event.connect.callerid,
				e->event.connect.dnid);
			else if(e->event.connect.dnid) {
				fprintf(f, "Call from '%s'", e->event.connect.dnid);
			} else if(e->event.connect.callerid) {
				fprintf(f, "Call from '%s'", e->event.connect.callerid);
			} else printf("Call from");
			fprintf(f, " (%s)\n", inet_ntoa(iax_get_peer_addr(e->session).sin_addr));

			if(most_recent_answer) {
				fprintf(f, "Incoming call ignored, there's already a call waiting for answer... \
please accept or reject first\n");
				iax_reject(e->session, "Too many calls, we're busy!");
			} else {
				if ( !(peer = malloc(sizeof(struct peer)))) {
					fprintf(f, "Warning: Unable to allocate memory!\n");
					return;
				}

				peer->time = time(0);
				peer->session = e->session;
				if (peer->gsmin)
					free(peer->gsmin);
				peer->gsmin = 0;
				if (peer->gsmout)
					free(peer->gsmout);
				peer->gsmout = 0;

				peer->next = peers;
				peers = peer;

				iax_accept(peer->session);
				iax_ring_announce(peer->session);
				most_recent_answer = peer;
				ringing = 1;
				gentone(TONE_RINGER, 0);
				fprintf(f, "Incoming call!\n");
			}
			issue_prompt(f);
		}
		iax_event_free(e);
	}