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; } }
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); }
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); }