2 * libiax: An implementation of Inter-Asterisk eXchange
4 * Copyright (C) 2001, Linux Support Services, Inc.
6 * Mark Spencer <markster@linux-support.net>
7 * Frik Strecker <frik@gatherworks.com>
9 * This program is free software, distributed under the terms of
10 * the GNU Lesser (Library) General Public License
17 #if defined(WIN32) || defined(_WIN32_WCE)
18 #undef __STRICT_ANSI__ //for strdup with ms
20 #if defined(_WIN32_WCE)
21 #define strdup _strdup
35 #if !defined(_WIN32_WCE)
36 #include <sys/timeb.h>
39 #define snprintf _snprintf
42 #define close closesocket
43 #if !defined(_WIN32_WCE)
44 #define inline __inline
48 #else // !#if defined(WIN32) || defined(_WIN32_WCE)
50 #include <sys/socket.h>
51 #include <netinet/in.h>
52 #include <sys/time.h> // gettimeofday
53 #ifndef HAVE_GETTIMEOFDAY
54 #define HAVE_GETTIMEOFDAY 1
70 #include <sys/select.h>
71 #include <netinet/in.h>
72 #include <arpa/inet.h>
75 // FlightGear: Modified to include FreeBSD
76 #if !defined(MACOSX) && !defined(__OpenBSD__) && !defined(__FreeBSD__)
83 #endif // #if defined(WIN32) || defined(_WIN32_WCE) yes or no
88 #include "jitterbuf.h"
89 #include "iax-client.h"
92 /* Define socket options for IAX2 sockets, based on platform
93 * availability of flags */
94 #if defined(WIN32) || defined(_WIN32_WCE)
95 #define IAX_SOCKOPTS 0
98 #define IAX_SOCKOPTS MSG_DONTWAIT
100 #if defined(SOLARIS) || defined(__OpenBSD__)
101 #define IAX_SOCKOPTS MSG_DONTWAIT
102 #else /* Linux and others */
103 #define IAX_SOCKOPTS MSG_DONTWAIT | MSG_NOSIGNAL
110 /* The snom phone seems to improperly execute memset in some cases */
111 #include "../../snom_phonecore2/include/snom_memset.h"
114 /* Voice TS Prediction causes libiax2 to clean up the timestamps on
115 * outgoing frames. It works best with either continuous voice, or
116 * callers who call iax_send_cng to indicate DTX for silence */
117 #define USE_VOICE_TS_PREDICTION
119 #define MIN_RETRY_TIME 10
120 #define MAX_RETRY_TIME 4000
121 #define MEMORY_SIZE 1000
123 #define TRANSFER_NONE 0
124 #define TRANSFER_BEGIN 1
125 #define TRANSFER_READY 2
126 #define TRANSFER_REL 3
128 /* Video frames bypass jitterbuffer */
129 static int video_bypass_jitterbuffer = 0;
131 /* To use or not to use the jitterbuffer */
132 static int iax_use_jitterbuffer = 1;
134 /* UDP Socket (file descriptor) */
135 static int netfd = -1;
138 static const int maxretries = 10;
140 /* configurable jitterbuffer options */
141 static long jb_target_extra = -1;
143 /* external global networking replacements */
144 static iax_sendto_t iax_sendto = (iax_sendto_t) sendto;
145 static iax_recvfrom_t iax_recvfrom = (iax_recvfrom_t) recvfrom;
147 /* ping interval (seconds) */
148 static int ping_time = 10;
149 static void send_ping(void *session);
154 /* session-local Sendto function */
156 /* Is voice quelched (e.g. hold) */
158 /* Codec Pref Order */
159 char codec_order[32];
160 /* Codec Pref Order Index*/
162 /* Last received voice format */
164 /* Last transmitted voice format */
166 /* Last received video format */
168 /* Last transmitted video format */
170 /* Per session capability */
172 /* Last received timestamp */
173 unsigned int last_ts;
174 /* Last transmitted timestamp */
175 unsigned int lastsent;
176 /* Timestamp of the last transmitted video frame */
177 unsigned int lastvsent;
178 #ifdef USE_VOICE_TS_PREDICTION
179 /* Next predicted voice ts */
180 unsigned int nextpred;
181 /* True if the last voice we transmitted was not silence/CNG */
184 /* Our last measured ping time */
185 unsigned int pingtime;
186 /* Address of peer */
187 struct sockaddr_in peeraddr;
188 /* Our call number */
190 /* Peer's call number */
192 /* Our next outgoing sequence number */
193 unsigned char oseqno;
194 /* Next sequence number they have not yet acknowledged */
195 unsigned char rseqno;
196 /* Our last received incoming sequence number */
197 unsigned char iseqno;
198 /* Last acknowledged sequence number */
199 unsigned char aseqno;
200 /* Last sequence number we VNAKd */
201 unsigned char lastvnak;
202 /* Time value that we base our transmission on */
203 struct timeval offset;
204 /* Time value we base our delivery on */
205 struct timeval rxcore;
206 /* Current link state */
208 /* Unregister reason */
209 char unregreason[MAXSTRLEN];
210 /* Expected Username */
211 char username[MAXSTRLEN];
212 /* Expected Secret */
213 char secret[MAXSTRLEN];
214 /* Refresh if applicable */
217 /* ping scheduler id */
221 struct sockaddr_in transfer;
225 int transferpeer; /* for attended transfer */
226 int transfer_moh; /* for music on hold while performing attended transfer */
230 struct iax_netstat remote_netstats;
232 /* For linking if there are multiple connections */
233 struct iax_session *next;
236 char iax_errstr[256];
239 #define IAXERROR snprintf(iax_errstr, sizeof(iax_errstr),
244 static int debug = 1;
246 static int debug = 0;
249 void iax_enable_debug(void)
254 void iax_disable_debug(void)
259 void iax_enable_jitterbuffer(void)
261 iax_use_jitterbuffer = 1;
264 void iax_disable_jitterbuffer(void)
266 iax_use_jitterbuffer = 0;
269 void iax_set_private(struct iax_session *s, void *ptr)
274 void *iax_get_private(struct iax_session *s)
279 void iax_set_sendto(struct iax_session *s, iax_sendto_t ptr)
284 /* This is a little strange, but to debug you call DEBU(G "Hello World!\n"); */
285 #if defined(WIN32) || defined(_WIN32_WCE)
286 #define G __FILE__, __LINE__,
288 #define G __FILE__, __LINE__, __PRETTY_FUNCTION__,
292 #if defined(WIN32) || defined(_WIN32_WCE)
293 static int __debug(const char *file, int lineno, const char *fmt, ...)
298 fprintf(stderr, "%s line %d: ", file, lineno);
299 vfprintf(stderr, fmt, args);
305 static int __debug(const char *file, int lineno, const char *func, const char *fmt, ...)
310 fprintf(stderr, "%s line %d in %s: ", file, lineno, func);
311 vfprintf(stderr, fmt, args);
317 #else /* No debug support */
319 #if defined(WIN32) || defined(_WIN32_WCE)
322 #define DEBU(fmt...) \
328 void iax_seed_random()
330 #if defined(HAVE_SRANDOMDEV)
332 #elif defined(HAVE_SRANDOM)
333 srandom((unsigned int)time(0));
334 #elif defined(HAVE_SRAND48)
335 srand48((long int)time(0));
337 srand((unsigned int)time(0));
343 #if defined(HAVE_RANDOM)
344 return (int)random();
345 #elif defined(HAVE_LRAND48)
346 return (int)lrand48();
352 typedef void (*sched_func)(void *);
355 /* These are scheduled things to be delivered */
357 /* If event is non-NULL then we're delivering an event */
358 struct iax_event *event;
359 /* If frame is non-NULL then we're transmitting a frame */
360 struct iax_frame *frame;
361 /* If func is non-NULL then we should call it */
363 /* and pass it this argument */
366 struct iax_sched *next;
369 static struct iax_sched *schedq = NULL;
370 static struct iax_session *sessions = NULL;
371 static int callnums = 1;
373 unsigned int iax_session_get_capability(struct iax_session *s)
375 return s->capability;
378 static int inaddrcmp(struct sockaddr_in *sin1, struct sockaddr_in *sin2)
380 return (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) || (sin1->sin_port != sin2->sin_port);
383 static int iax_sched_add(struct iax_event *event, struct iax_frame *frame, sched_func func, void *arg, int ms)
386 /* Schedule event to be delivered to the client
387 in ms milliseconds from now, or a reliable frame to be retransmitted */
388 struct iax_sched *sched, *cur, *prev = NULL;
390 if (!event && !frame && !func) {
391 DEBU(G "No event, no frame, no func? what are we scheduling?\n");
395 //fprintf(stderr, "scheduling event %d ms from now\n", ms);
396 sched = (struct iax_sched*)malloc(sizeof(struct iax_sched));
398 memset(sched, 0, sizeof(struct iax_sched));
399 sched->when = iax_tvnow();
400 sched->when.tv_sec += (ms / 1000);
402 sched->when.tv_usec += (ms * 1000);
403 if (sched->when.tv_usec > 1000000) {
404 sched->when.tv_usec -= 1000000;
405 sched->when.tv_sec++;
407 sched->event = event;
408 sched->frame = frame;
411 /* Put it in the list, in order */
413 while(cur && ((cur->when.tv_sec < sched->when.tv_sec) ||
414 ((cur->when.tv_usec <= sched->when.tv_usec) &&
415 (cur->when.tv_sec == sched->when.tv_sec)))) {
427 DEBU(G "Out of memory!\n");
432 static int iax_sched_del(struct iax_event *event, struct iax_frame *frame, sched_func func, void *arg, int all)
434 struct iax_sched *cur, *tmp, *prev = NULL;
438 if (cur->event == event && cur->frame == frame && cur->func == func && cur->arg == arg) {
440 prev->next = cur->next;
457 int iax_time_to_next_event(void)
460 struct iax_sched *cur = schedq;
461 int ms, min = 999999999;
463 /* If there are no pending events, we don't need to timeout */
468 ms = (cur->when.tv_sec - tv.tv_sec) * 1000 +
469 (cur->when.tv_usec - tv.tv_usec) / 1000;
479 struct iax_session *iax_session_new(void)
481 struct iax_session *s;
482 s = calloc(1, sizeof(struct iax_session));
486 /* Initialize important fields */
488 s->svoiceformat = -1;
490 /* Default pingtime to 100 ms -- should cover most decent net connections */
492 /* XXX Not quite right -- make sure it's not in use, but that won't matter
493 unless you've had at least 65k calls. XXX */
494 s->callno = callnums++;
495 if (callnums > 32767)
499 s->transferpeer = 0; /* for attended transfer */
501 s->sendto = iax_sendto;
504 #ifdef USE_VOICE_TS_PREDICTION
514 jbconf.max_jitterbuf = 0;
515 jbconf.resync_threshold = 1000;
516 jbconf.max_contig_interp = 0;
517 jbconf.target_extra = jb_target_extra;
518 jb_setconf(s->jb, &jbconf);
525 static int iax_session_valid(struct iax_session *session)
527 /* Return -1 on a valid iax session pointer, 0 on a failure */
528 struct iax_session *cur = sessions;
537 int iax_get_netstats(struct iax_session *session, int *rtt, struct iax_netstat *local, struct iax_netstat *remote)
541 if(!iax_session_valid(session)) return -1;
543 *rtt = session->pingtime;
545 *remote = session->remote_netstats;
547 jb_getinfo(session->jb, &stats);
549 local->jitter = stats.jitter;
550 /* XXX: should be short-term loss pct.. */
551 if(stats.frames_in == 0) stats.frames_in = 1;
552 local->losspct = stats.losspct/1000;
553 local->losscnt = stats.frames_lost;
554 local->packets = stats.frames_in;
555 local->delay = stats.current - stats.min;
556 local->dropped = stats.frames_dropped;
557 local->ooo = stats.frames_ooo;
562 #ifdef USE_VOICE_TS_PREDICTION
563 static void add_ms(struct timeval *tv, int ms)
565 tv->tv_usec += ms * 1000;
566 if (tv->tv_usec > 999999) {
567 tv->tv_sec += tv->tv_usec / 1000000;
568 tv->tv_usec %= 1000000;
571 if (tv->tv_usec < 0) {
572 tv->tv_sec += (tv->tv_usec / 1000000 - 1);
573 tv->tv_usec = (tv->tv_usec % 1000000) + 1000000;
578 static int calc_timestamp(struct iax_session *session, unsigned int ts, struct ast_frame *f)
586 if ( f && f->frametype == AST_FRAME_VOICE )
589 } else if ( f && f->frametype == AST_FRAME_VIDEO )
592 } else if (!f || f->frametype == AST_FRAME_IAX)
597 /* If this is the first packet we're sending, get our
599 if (!session->offset.tv_sec && !session->offset.tv_usec)
600 session->offset = iax_tvnow();
602 /* If the timestamp is specified, just use their specified
603 timestamp no matter what. Usually this is done for
608 session->lastsent = ts;
612 /* Otherwise calculate the timestamp from the current time */
615 /* Calculate the number of milliseconds since we sent the first packet */
616 ms = (tv.tv_sec - session->offset.tv_sec) * 1000 +
617 (tv.tv_usec - session->offset.tv_usec) / 1000;
623 #ifdef USE_VOICE_TS_PREDICTION
624 /* If we haven't most recently sent silence, and we're
625 * close in time, use predicted time */
626 if(session->notsilenttx && abs(ms - session->nextpred) <= 240) {
627 /* Adjust our txcore, keeping voice and non-voice
629 add_ms(&session->offset, (int)(ms - session->nextpred)/10);
631 if(!session->nextpred)
632 session->nextpred = ms;
633 ms = session->nextpred;
635 /* in this case, just use the actual time, since
636 * we're either way off (shouldn't happen), or we're
637 * ending a silent period -- and seed the next predicted
638 * time. Also, round ms to the next multiple of
639 * frame size (so our silent periods are multiples
640 * of frame size too) */
641 int diff = ms % (f->samples / 8);
643 ms += f->samples/8 - diff;
644 session->nextpred = ms;
646 session->notsilenttx = 1;
648 if(ms <= session->lastsent)
649 ms = session->lastsent + 3;
651 } else if ( video ) {
653 * IAX2 draft 03 says that timestamps MUST be in order.
654 * It does not say anything about several frames having the same timestamp
655 * When transporting video, we can have a frame that spans multiple iax packets
656 * (so called slices), so it would make sense to use the same timestamp for all of
658 * We do want to make sure that frames don't go backwards though
660 if ( (unsigned int)ms < session->lastsent )
661 ms = session->lastsent;
663 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking)
664 if appropriate unless it's a genuine frame */
666 if ((unsigned int)ms <= session->lastsent)
667 ms = session->lastsent + 3;
668 } else if (abs(ms - session->lastsent) <= 240) {
669 ms = session->lastsent + 3;
674 /* Record the last sent packet for future reference */
675 /* unless an AST_FRAME_IAX */
677 session->lastsent = ms;
679 #ifdef USE_VOICE_TS_PREDICTION
680 /* set next predicted ts based on 8khz samples */
682 session->nextpred += f->samples / 8;
688 static unsigned char get_n_bits_at(unsigned char *data, int n, int bit)
690 int byte = bit / 8; /* byte containing first bit */
691 int rem = 8 - (bit % 8); /* remaining bits in first byte */
692 unsigned char ret = 0;
698 ret = (data[byte] << (n - rem));
699 ret |= (data[byte + 1] >> (8 - n + rem));
701 ret = (data[byte] >> (rem - n));
704 return (ret & (0xff >> (8 - n)));
707 static int speex_get_wb_sz_at(unsigned char *data, int len, int bit)
709 static int SpeexWBSubModeSz[] = {
715 /* skip up to two wideband frames */
716 if (((len * 8 - off) >= 5) &&
717 get_n_bits_at(data, 1, off)) {
718 c = get_n_bits_at(data, 3, off + 1);
719 off += SpeexWBSubModeSz[c];
721 if (((len * 8 - off) >= 5) &&
722 get_n_bits_at(data, 1, off)) {
723 c = get_n_bits_at(data, 3, off + 1);
724 off += SpeexWBSubModeSz[c];
726 if (((len * 8 - off) >= 5) &&
727 get_n_bits_at(data, 1, off)) {
728 /* too many in a row */
729 DEBU(G "\tCORRUPT too many wideband streams in a row\n");
738 static int speex_get_samples(unsigned char *data, int len)
740 static int SpeexSubModeSz[] = {
745 static int SpeexInBandSz[] = {
755 DEBU(G "speex_get_samples(%d)\n", len);
756 while ((len * 8 - bit) >= 5) {
757 /* skip wideband frames */
758 off = speex_get_wb_sz_at(data, len, bit);
760 DEBU(G "\tERROR reading wideband frames\n");
765 if ((len * 8 - bit) < 5) {
766 DEBU(G "\tERROR not enough bits left after wb\n");
770 /* get control bits */
771 c = get_n_bits_at(data, 5, bit);
772 DEBU(G "\tCONTROL: %d at %d\n", c, bit);
776 DEBU(G "\tTERMINATOR\n");
778 } else if (c == 14) {
779 /* in-band signal; next 4 bits contain signal id */
780 c = get_n_bits_at(data, 4, bit);
782 DEBU(G "\tIN-BAND %d bits\n", SpeexInBandSz[c]);
783 bit += SpeexInBandSz[c];
784 } else if (c == 13) {
785 /* user in-band; next 5 bits contain msg len */
786 c = get_n_bits_at(data, 5, bit);
788 DEBU(G "\tUSER-BAND %d bytes\n", c);
791 DEBU(G "\tUNKNOWN sub-mode %d\n", c);
794 /* skip number bits for submode (less the 5 control bits) */
795 DEBU(G "\tSUBMODE %d %d bits\n", c, SpeexSubModeSz[c]);
796 bit += SpeexSubModeSz[c] - 5;
798 cnt += 160; /* new frame */
801 DEBU(G "\tSAMPLES: %d\n", cnt);
805 static inline int get_interp_len(int format)
807 return (format == AST_FORMAT_ILBC) ? 30 : 20;
810 static int get_sample_cnt(struct iax_event *e)
815 * In the case of zero length frames, do not return a cnt of 0
817 if ( e->datalen == 0 ) {
818 return get_interp_len( e->subclass ) * 8;
821 switch (e->subclass) {
822 case AST_FORMAT_SPEEX:
823 cnt = speex_get_samples(e->data, e->datalen);
825 case AST_FORMAT_G723_1:
826 cnt = 240; /* FIXME Not always the case */
828 case AST_FORMAT_ILBC:
829 cnt = 240 * (e->datalen / 50);
832 cnt = 160 * (e->datalen / 33);
834 case AST_FORMAT_G729A:
835 cnt = 160 * (e->datalen / 20);
837 case AST_FORMAT_SLINEAR:
838 cnt = e->datalen / 2;
840 case AST_FORMAT_LPC10:
841 cnt = 22 * 8 + (((char *)(e->data))[7] & 0x1) * 8;
843 case AST_FORMAT_ULAW:
844 case AST_FORMAT_ALAW:
847 case AST_FORMAT_ADPCM:
848 case AST_FORMAT_G726:
849 cnt = e->datalen * 2;
857 static int iax_xmit_frame(struct iax_frame *f)
862 struct ast_iax2_full_hdr *h = (struct ast_iax2_full_hdr *)f->data;
864 if (ntohs(h->scallno) & IAX_FLAG_FULL)
865 iax_showframe(f, NULL, 0, f->transfer ?
866 &(f->session->transfer) :
867 &(f->session->peeraddr),
868 f->datalen - sizeof(struct ast_iax2_full_hdr));
871 /* Send the frame raw */
872 res = f->session->sendto(netfd, (const char *) f->data, f->datalen,
873 IAX_SOCKOPTS, f->transfer ?
874 (struct sockaddr *)&(f->session->transfer) :
875 (struct sockaddr *)&(f->session->peeraddr),
876 sizeof(f->session->peeraddr));
880 static int iax_reliable_xmit(struct iax_frame *f)
882 struct iax_frame *fc;
883 struct ast_iax2_full_hdr *fh;
884 fh = (struct ast_iax2_full_hdr *) f->data;
888 fc = (struct iax_frame *)malloc(sizeof(struct iax_frame));
890 /* Make a copy of the frame */
891 memcpy(fc, f, sizeof(struct iax_frame));
892 /* And a copy of the data if applicable */
893 if (!fc->data || !fc->datalen) {
894 IAXERROR "No frame data?");
895 DEBU(G "No frame data?\n");
898 fc->data = (char *)malloc(fc->datalen);
900 DEBU(G "Out of memory\n");
901 IAXERROR "Out of memory\n");
904 memcpy(fc->data, f->data, f->datalen);
905 iax_sched_add(NULL, fc, NULL, NULL, fc->retrytime);
906 return iax_xmit_frame(fc);
912 void iax_set_networking(iax_sendto_t st, iax_recvfrom_t rf)
918 void iax_set_jb_target_extra( long value )
920 /* store in jb_target_extra, a static global */
921 jb_target_extra = value ;
924 int iax_init(int preferredportno)
926 int portno = preferredportno;
927 #ifndef _MSC_VER // avoid compare of address of imported function
928 /* MSVC only - In certain circumstances the addresses placed in iax_sendto and iax_recvfrom
929 can be an offset to a jump table, making a compare of the current address to the address
930 of the actual imported function fail. */
931 if (iax_recvfrom == (iax_recvfrom_t)recvfrom)
934 struct sockaddr_in sin;
937 int bufsize = 128 * 1024;
941 /* Okay, just don't do anything */
942 DEBU(G "Already initialized.");
945 netfd = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
948 DEBU(G "Unable to allocate UDP socket\n");
949 IAXERROR "Unable to allocate UDP socket\n");
953 if (preferredportno == 0)
954 preferredportno = IAX_DEFAULT_PORTNO;
956 if (preferredportno < 0)
959 sin.sin_family = AF_INET;
960 sin.sin_addr.s_addr = 0;
961 sin.sin_port = htons((short)preferredportno);
962 if (bind(netfd, (struct sockaddr *) &sin, sizeof(sin)) < 0)
964 #if defined(WIN32) || defined(_WIN32_WCE)
965 if (WSAGetLastError() == WSAEADDRINUSE)
967 if (errno == EADDRINUSE)
970 /*the port is already in use, so bind to a free port chosen by the IP stack*/
971 DEBU(G "Unable to bind to preferred port - port is in use. Trying to bind to a free one");
972 sin.sin_port = htons((short)0);
973 if (bind(netfd, (struct sockaddr *) &sin, sizeof(sin)) < 0)
975 IAXERROR "Unable to bind UDP socket\n");
980 IAXERROR "Unable to bind UDP socket\n");
985 sinlen = sizeof(sin);
986 if (getsockname(netfd, (struct sockaddr *) &sin, &sinlen) < 0)
990 DEBU(G "Unable to figure out what I'm bound to.");
991 IAXERROR "Unable to determine bound port number.");
994 #if defined(WIN32) || defined(_WIN32_WCE)
996 if (ioctlsocket(netfd,FIONBIO,(unsigned long *) &flags))
1000 DEBU(G "Unable to set non-blocking mode.");
1001 IAXERROR "Unable to set non-blocking mode.");
1006 if ((flags = fcntl(netfd, F_GETFL)) < 0)
1010 DEBU(G "Unable to retrieve socket flags.");
1011 IAXERROR "Unable to retrieve socket flags.");
1014 if (fcntl(netfd, F_SETFL, flags | O_NONBLOCK) < 0)
1018 DEBU(G "Unable to set non-blocking mode.");
1019 IAXERROR "Unable to set non-blocking mode.");
1023 /* Mihai: increase UDP socket buffers to avoid packet loss. */
1024 if (setsockopt(netfd, SOL_SOCKET, SO_RCVBUF, (char *)&bufsize,
1025 sizeof(bufsize)) < 0)
1027 DEBU(G "Unable to set receive buffer size.");
1028 IAXERROR "Unable to set receive buffer size.");
1031 /* set send buffer size too */
1032 if (setsockopt(netfd, SOL_SOCKET, SO_SNDBUF, (char *)&bufsize,
1033 sizeof(bufsize)) < 0)
1035 DEBU(G "Unable to set send buffer size.");
1036 IAXERROR "Unable to set send buffer size.");
1039 portno = ntohs(sin.sin_port);
1040 DEBU(G "Started on port %d\n", portno);
1044 callnums = 1 + (int)(32767.0 * (iax_random() / (RAND_MAX + 1.0)));
1049 static void destroy_session(struct iax_session *session);
1051 static void convert_reply(char *out, unsigned char *in)
1055 sprintf(out + (x << 1), "%2.2x", (int)in[x]);
1058 static unsigned char compress_subclass(int subclass)
1062 /* If it's 128 or smaller, just return it */
1063 if (subclass < IAX_FLAG_SC_LOG)
1065 /* Otherwise find its power */
1066 for (x = 0; x < IAX_MAX_SHIFT; x++) {
1067 if (subclass & (1 << x)) {
1069 DEBU(G "Can't compress subclass %d\n", subclass);
1075 return power | IAX_FLAG_SC_LOG;
1078 static int iax_send(struct iax_session *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final, int fullframe)
1080 /* Queue a packet for delivery on a given private structure. Use "ts" for
1081 timestamp, or calculate if ts is 0. Send immediately without retransmission
1082 or delayed, with retransmission */
1083 struct ast_iax2_full_hdr *fh;
1084 struct ast_iax2_mini_hdr *mh;
1085 struct ast_iax2_video_hdr *vh;
1086 //unsigned char buf[5120]; //fd: changed max packet size[5120];
1087 unsigned char buf[32 * 1024]; //Mihai: let's see if this is where it crashes
1089 struct iax_frame *fr;
1092 unsigned int lastsent;
1097 IAXERROR "No private structure for packet?\n");
1101 /* this must come before the next call to calc_timestamp() since
1102 calc_timestamp() will change lastsent to the returned value */
1103 lastsent = pvt->lastsent;
1105 /* Calculate actual timestamp */
1106 fts = calc_timestamp(pvt, ts, f);
1108 if (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L))
1109 /* High two bits are the same on timestamp, or sending on a trunk */ &&
1110 (f->frametype == AST_FRAME_VOICE)
1111 /* is a voice frame */ &&
1112 (f->subclass == pvt->svoiceformat)
1113 /* is the same type */ )
1115 /* Force immediate rather than delayed transmission */
1117 /* Mark that mini-style frame is appropriate */
1121 /* Bitmask taken from chan_iax2.c... I must ask Mark Spencer for this? I think not... */
1122 if ( f->frametype == AST_FRAME_VIDEO )
1124 /* Check if the timestamp has rolled over or if the video codec has changed */
1125 if ( ((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
1126 (f->subclass == pvt->svideoformat)
1129 /* send a mini video frame immediately */
1134 /* we want to send a fullframe and be able to retransmit it */
1138 pvt->lastvsent = fts;
1141 /* if requested, force a full frame */
1148 /* Allocate an iax_frame */
1151 fr = (struct iax_frame *) buf;
1154 fr = iax_frame_new(DIRECTION_OUTGRESS, f->datalen);
1157 IAXERROR "Out of memory\n");
1162 /* Copy our prospective frame into our immediate or retransmitted wrapper */
1163 iax_frame_wrap(fr, f);
1168 IAXERROR "timestamp is 0?\n");
1174 fr->callno = pvt->callno;
1175 fr->transfer = transfer;
1180 /* We need a full frame */
1184 fr->oseqno = pvt->oseqno++;
1185 fr->iseqno = pvt->iseqno;
1186 fh = (struct ast_iax2_full_hdr *)(((char *)fr->af.data) - sizeof(struct ast_iax2_full_hdr));
1187 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
1188 fh->ts = htonl(fr->ts);
1189 fh->oseqno = fr->oseqno;
1194 fh->iseqno = fr->iseqno;
1195 /* Keep track of the last thing we've acknowledged */
1196 pvt->aseqno = fr->iseqno;
1197 fh->type = fr->af.frametype & 0xFF;
1198 if (f->frametype == AST_FRAME_VIDEO)
1199 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
1201 fh->csub = compress_subclass(fr->af.subclass);
1204 fr->dcallno = pvt->transfercallno;
1206 fr->dcallno = pvt->peercallno;
1207 fh->dcallno = htons(fr->dcallno);
1208 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
1210 fr->retries = maxretries;
1211 /* Retry after 2x the ping time has passed */
1212 fr->retrytime = pvt->pingtime * 2;
1213 if (fr->retrytime < MIN_RETRY_TIME)
1214 fr->retrytime = MIN_RETRY_TIME;
1215 if (fr->retrytime > MAX_RETRY_TIME)
1216 fr->retrytime = MAX_RETRY_TIME;
1217 /* Acks' don't get retried */
1218 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
1220 if (f->frametype == AST_FRAME_VOICE)
1222 pvt->svoiceformat = f->subclass;
1224 else if (f->frametype == AST_FRAME_VIDEO)
1226 pvt->svideoformat = f->subclass & ~0x1;
1230 res = iax_xmit_frame(fr);
1232 res = iax_reliable_xmit(fr);
1235 if (fr->af.frametype == AST_FRAME_VIDEO)
1237 /* Video frame have no sequence number */
1240 vh = (struct ast_iax2_video_hdr *)(((char* )fr->af.data) - sizeof(struct ast_iax2_video_hdr));
1242 vh->callno = htons(0x8000 | fr->callno);
1243 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
1244 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
1247 res = iax_xmit_frame(fr);
1250 /* Mini-frames have no sequence number */
1253 /* Mini frame will do */
1254 mh = (struct ast_iax2_mini_hdr *)(((char *)fr->af.data) - sizeof(struct ast_iax2_mini_hdr));
1255 mh->callno = htons(fr->callno);
1256 mh->ts = htons(fr->ts & 0xFFFF);
1257 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
1260 res = iax_xmit_frame(fr);
1263 if( !now && fr!=NULL )
1264 iax_frame_free( fr );
1269 static int iax_predestroy(struct iax_session *pvt)
1274 if (!pvt->alreadygone) {
1275 /* No more pings or lagrq's */
1276 if (pvt->pingid > -1)
1277 ast_sched_del(sched, pvt->pingid);
1278 if (pvt->lagid > -1)
1279 ast_sched_del(sched, pvt->lagid);
1280 if (pvt->autoid > -1)
1281 ast_sched_del(sched, pvt->autoid);
1282 if (pvt->initid > -1)
1283 ast_sched_del(sched, pvt->initid);
1288 pvt->alreadygone = 1;
1294 static int __send_command(struct iax_session *i, char type, int command,
1295 unsigned int ts, unsigned char *data, int datalen, int seqno,
1296 int now, int transfer, int final, int fullframe, int samples)
1300 f.subclass = command;
1301 f.datalen = datalen;
1302 f.samples = samples;
1306 f.src = (char *) __FUNCTION__;
1308 f.src = (char *) __FILE__;
1311 return iax_send(i, &f, ts, seqno, now, transfer, final, fullframe);
1314 static int send_command(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen, int seqno)
1316 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0, 0, 0);
1319 static int send_command_video(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen, int seqno, int fullframe)
1321 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0, fullframe, 0);
1324 static int send_command_final(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen, int seqno)
1327 /* It is assumed that the callno has already been locked */
1331 r = __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1, 0, 0);
1332 if (r >= 0) destroy_session(i);
1336 static int send_command_immediate(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen, int seqno)
1338 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0, 0, 0);
1341 static int send_command_transfer(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen)
1343 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0, 0, 0);
1346 static int send_command_samples(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen, int seqno, int samples)
1348 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0, 0, samples);
1352 int iax_transfer(struct iax_session *session, const char *number)
1354 static int res; //Return Code
1355 struct iax_ie_data ied; //IE Data Structure (Stuff To Send)
1357 // Clear The Memory Used For IE Buffer
1358 memset(&ied, 0, sizeof(ied));
1360 // Copy The Transfer Destination Into The IE Structure
1361 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, number);
1363 // Send The Transfer Command - Asterisk Will Handle The Rest!
1364 res = send_command(session, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
1370 static void stop_transfer(struct iax_session *session)
1372 struct iax_sched *sch;
1376 if (sch->frame && (sch->frame->session == session))
1377 sch->frame->retries = -1;
1380 } /* stop_transfer */
1382 static void complete_transfer(struct iax_session *session, int peercallno, int xfr2peer, int preserveSeq)
1386 session->peercallno = peercallno;
1387 /* Change from transfer to session now */
1389 memcpy(&session->peeraddr, &session->transfer, sizeof(session->peeraddr));
1390 memset(&session->transfer, 0, sizeof(session->transfer));
1391 session->transferring = TRANSFER_NONE;
1392 session->transferpeer = 0;
1393 session->transfer_moh = 0;
1394 /* Force retransmission of a real voice packet, and reset all timing */
1395 session->svoiceformat = -1;
1396 session->voiceformat = 0;
1397 session->svideoformat = -1;
1398 session->videoformat = 0;
1401 memset(&session->rxcore, 0, sizeof(session->rxcore));
1402 memset(&session->offset, 0, sizeof(session->offset));
1404 /* Reset jitterbuffer */
1405 while(jb_getall(session->jb,&frame) == JB_OK)
1406 iax_event_free((struct iax_event *)frame.data);
1408 jb_reset(session->jb);
1412 /* Reset sequence numbers */
1413 session->aseqno = 0;
1414 session->oseqno = 0;
1415 session->iseqno = 0;
1418 session->lastsent = 0;
1419 session->last_ts = 0;
1420 session->pingtime = 30;
1421 /* We have to dump anything we were going to (re)transmit now that we've been
1422 transferred since they're all invalid and for the old host. */
1423 stop_transfer(session);
1424 } /* complete_transfer */
1426 int iax_setup_transfer(struct iax_session *org_session, struct iax_session *new_session)
1429 struct iax_ie_data ied0;
1430 struct iax_ie_data ied1;
1432 struct iax_session *s0 = org_session;
1433 struct iax_session *s1 = new_session;
1435 int transfer_id = 1 + (int)(32767.0 * (iax_random() / (RAND_MAX + 1.0)));
1437 memset(&ied0, 0, sizeof(ied0));
1439 memset(&ied1, 0, sizeof(ied1));
1441 /* reversed setup */
1442 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &s1->peeraddr);
1443 iax_ie_append_short(&ied0, IAX_IE_CALLNO, s1->peercallno);
1444 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transfer_id);
1446 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &s0->peeraddr);
1447 iax_ie_append_short(&ied1, IAX_IE_CALLNO, s0->peercallno);
1448 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transfer_id);
1450 s0->transfer = s1->peeraddr;
1451 s1->transfer = s0->peeraddr;
1453 s0->transferid = transfer_id;
1454 s1->transferid = transfer_id;
1456 s0->transfercallno = s0->peercallno;
1457 s1->transfercallno = s1->peercallno;
1459 s0->transferring = TRANSFER_BEGIN;
1460 s1->transferring = TRANSFER_BEGIN;
1462 s0->transferpeer = s1->callno;
1463 s1->transferpeer = s0->callno;
1464 #ifdef DEBUG_SUPPORT
1466 DEBU(G "iax_setup_transfer(%d, %d) transfer_id=%d\n", s0->callno, s1->callno, transfer_id);
1467 DEBU(G "\torg: callno=%d peercallno=%d peeraddr=%s peerport=%d\n", s0->callno, s0->peercallno, inet_ntoa(s0->peeraddr.sin_addr), ntohs(s0->peeraddr.sin_port));
1468 DEBU(G "\tnew: callno=%d peercallno=%d peeraddr=%s peerport=%d\n", s1->callno, s1->peercallno, inet_ntoa(s1->peeraddr.sin_addr), ntohs(s1->peeraddr.sin_port));
1472 res = send_command(s0, AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
1477 res = send_command(s1, AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
1485 static int iax_finish_transfer(struct iax_session *s, short new_peer)
1488 struct iax_ie_data ied;
1490 memset(&ied, 0, sizeof(ied));
1492 iax_ie_append_short(&ied, IAX_IE_CALLNO, new_peer);
1494 res = send_command(s, AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied.buf, ied.pos, -1);
1496 complete_transfer(s, new_peer, 0, 1);
1502 static struct iax_session *iax_find_session2(short callno)
1504 struct iax_session *cur = sessions;
1507 if (callno == cur->callno && callno != 0) {
1516 static int iax_handle_txready(struct iax_session *s)
1518 struct iax_session *s0, *s1;
1519 short s0_org_peer, s1_org_peer;
1521 if (s->transfer_moh) {
1522 s->transfer_moh = 0;
1526 complete_transfer(s, s->peercallno, 0, 1);
1528 s->transferring = TRANSFER_REL;
1531 s1 = iax_find_session2(s0->transferpeer);
1534 s1->callno == s0->transferpeer &&
1535 s0->transferring == TRANSFER_REL &&
1536 s1->transferring == TRANSFER_REL) {
1538 s0_org_peer = s0->peercallno;
1539 s1_org_peer = s1->peercallno;
1541 iax_finish_transfer(s0, s1_org_peer);
1542 iax_finish_transfer(s1, s0_org_peer);
1549 static void iax_handle_txreject(struct iax_session *s)
1551 struct iax_session *s0, *s1;
1554 s1 = iax_find_session2(s0->transferpeer);
1556 s0->transferpeer == s1->callno &&
1558 if (s1->transfer_moh) {
1559 s1->transfer_moh = 0;
1560 send_command_immediate(s1, AST_FRAME_IAX, IAX_COMMAND_UNQUELCH, 0, NULL, 0, s1->iseqno);
1563 if (s0->transfer_moh) {
1564 s0->transfer_moh = 0;
1565 send_command_immediate(s0, AST_FRAME_IAX, IAX_COMMAND_UNQUELCH, 0, NULL, 0, s0->iseqno);
1568 memset(&s->transfer, 0, sizeof(s->transfer));
1569 s->transferring = TRANSFER_NONE;
1570 s->transferpeer = 0;
1571 s->transfer_moh = 0;
1574 static void destroy_session(struct iax_session *session)
1576 struct iax_session *cur, *prev=NULL;
1577 struct iax_sched *curs, *prevs=NULL, *nexts=NULL;
1582 if (curs->frame && curs->frame->session == session) {
1583 /* Just mark these frames as if they've been sent */
1584 curs->frame->retries = -1;
1585 } else if (curs->event && curs->event->session == session) {
1587 prevs->next = nexts;
1591 iax_event_free(curs->event);
1602 if (cur == session) {
1606 prev->next = session->next;
1608 sessions = session->next;
1610 while(jb_getall(session->jb,&frame) == JB_OK)
1611 iax_event_free((struct iax_event *)frame.data);
1613 jb_destroy(session->jb);
1623 static int iax_send_lagrp(struct iax_session *session, unsigned int ts);
1624 static int iax_send_pong(struct iax_session *session, unsigned int ts);
1626 static struct iax_event *handle_event(struct iax_event *event)
1628 /* We have a candidate event to be delievered. Be sure
1629 the session still exists. */
1632 if ( event->etype == IAX_EVENT_NULL ) return event;
1633 if (iax_session_valid(event->session))
1635 /* Lag requests are never actually sent to the client, but
1636 other than that are handled as normal packets */
1637 switch(event->etype)
1639 /* the user on the outside may need to look at the session so we will not free
1640 it here anymore we will test for hangup event in iax_event_free and do it
1643 case IAX_EVENT_REJECT:
1644 case IAX_EVENT_HANGUP:
1645 /* Destroy this session -- it's no longer valid */
1646 destroy_session(event->session);
1648 case IAX_EVENT_LAGRQ:
1649 event->etype = IAX_EVENT_LAGRP;
1650 iax_send_lagrp(event->session, event->ts);
1651 iax_event_free(event);
1653 case IAX_EVENT_PING:
1654 event->etype = IAX_EVENT_PONG;
1655 iax_send_pong(event->session, event->ts);
1656 iax_event_free(event);
1658 case IAX_EVENT_POKE:
1659 event->etype = IAX_EVENT_PONG;
1660 iax_send_pong(event->session, event->ts);
1661 destroy_session(event->session);
1662 iax_event_free(event);
1668 iax_event_free(event);
1673 static int iax2_vnak(struct iax_session *session)
1675 /* send vnak just once for a given sequence number */
1676 if ( (unsigned char)(session->lastvnak - session->iseqno) < 128 )
1681 session->lastvnak = session->iseqno;
1682 return send_command_immediate(session, AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, session->iseqno);
1685 int iax_send_dtmf(struct iax_session *session, char digit)
1687 return send_command(session, AST_FRAME_DTMF, digit, 0, NULL, 0, -1);
1690 int iax_send_voice(struct iax_session *session, int format, unsigned char *data, int datalen, int samples)
1692 /* Send a (possibly compressed) voice frame */
1693 if (!session->quelch)
1694 return send_command_samples(session, AST_FRAME_VOICE, format, 0, data, datalen, -1, samples);
1698 int iax_send_cng(struct iax_session *session, int level, unsigned char *data,
1701 #ifdef USE_VOICE_TS_PREDICTION
1702 session->notsilenttx = 0;
1704 return send_command(session, AST_FRAME_CNG, level, 0, data, datalen, -1);
1707 int iax_send_image(struct iax_session *session, int format, unsigned char *data,
1710 /* Send an image frame */
1711 return send_command(session, AST_FRAME_IMAGE, format, 0, data, datalen, -1);
1714 int iax_send_video(struct iax_session *session, int format, unsigned char *data,
1715 int datalen, int fullframe)
1717 if (!session->quelch)
1719 int res = send_command_video(session, AST_FRAME_VIDEO, format,
1720 0, data, datalen, -1, fullframe);
1726 int iax_send_video_trunk(struct iax_session *session, int format,
1727 char *data, int datalen, int fullframe, int ntrunk)
1729 static int my_lastts = 0;
1732 my_lastts = calc_timestamp(session, 0, NULL);
1734 if ( !session->quelch )
1736 return send_command_video(session, AST_FRAME_VIDEO, format,
1737 my_lastts, (unsigned char *)data, datalen, -1,
1743 int iax_video_bypass_jitter(struct iax_session *s, int mode)
1745 video_bypass_jitterbuffer = mode;
1749 int iax_register(struct iax_session *session, const char *server, const char *peer, const char *secret, int refresh)
1751 /* Send a registration request */
1755 int portno = IAX_DEFAULT_PORTNO;
1756 struct iax_ie_data ied;
1760 strncpy(tmp, server, sizeof(tmp) - 1);
1761 p = strchr(tmp, ':');
1767 memset(&ied, 0, sizeof(ied));
1769 strncpy(session->secret, secret, sizeof(session->secret) - 1);
1771 strcpy(session->secret, "");
1773 memset(&session->unregreason, 0, sizeof(session->unregreason));
1776 hp = gethostbyname(tmp);
1778 snprintf(iax_errstr, sizeof(iax_errstr), "Invalid hostname: %s", tmp);
1781 memcpy(&session->peeraddr.sin_addr, hp->h_addr, sizeof(session->peeraddr.sin_addr));
1782 session->peeraddr.sin_port = htons(portno);
1783 session->peeraddr.sin_family = AF_INET;
1784 strncpy(session->username, peer, sizeof(session->username) - 1);
1785 session->refresh = refresh;
1786 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer);
1787 iax_ie_append_short(&ied, IAX_IE_REFRESH, refresh);
1788 res = send_command(session, AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
1792 int iax_unregister(struct iax_session *session, const char *server, const char *peer, const char *secret, const char *reason)
1794 /* Send an unregistration request */
1797 int portno = IAX_DEFAULT_PORTNO;
1798 struct iax_ie_data ied;
1802 strncpy(tmp, server, sizeof(tmp) - 1);
1803 p = strchr(tmp, ':');
1809 memset(&ied, 0, sizeof(ied));
1811 strncpy(session->secret, secret, sizeof(session->secret) - 1);
1813 strcpy(session->secret, "");
1815 if (reason && strlen(reason))
1816 strncpy(session->unregreason, reason, sizeof(session->unregreason) - 1);
1818 strcpy(session->unregreason, "Unspecified");
1821 hp = gethostbyname(tmp);
1823 snprintf(iax_errstr, sizeof(iax_errstr), "Invalid hostname: %s", tmp);
1826 memcpy(&session->peeraddr.sin_addr, hp->h_addr, sizeof(session->peeraddr.sin_addr));
1827 session->peeraddr.sin_port = htons(portno);
1828 session->peeraddr.sin_family = AF_INET;
1829 strncpy(session->username, peer, sizeof(session->username) - 1);
1830 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer);
1831 iax_ie_append_str(&ied, IAX_IE_CAUSE, session->unregreason);
1832 return send_command(session, AST_FRAME_IAX, IAX_COMMAND_REGREL, 0, ied.buf, ied.pos, -1);
1835 int iax_reject(struct iax_session *session, char *reason)
1837 struct iax_ie_data ied;
1838 memset(&ied, 0, sizeof(ied));
1839 iax_ie_append_str(&ied, IAX_IE_CAUSE, reason ? reason : "Unspecified");
1840 return send_command_final(session, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
1843 int iax_hangup(struct iax_session *session, char *byemsg)
1845 struct iax_ie_data ied;
1846 iax_sched_del(NULL, NULL, send_ping, (void *) session, 1);
1847 memset(&ied, 0, sizeof(ied));
1848 iax_ie_append_str(&ied, IAX_IE_CAUSE, byemsg ? byemsg : "Normal clearing");
1849 return send_command_final(session, AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
1852 int iax_sendurl(struct iax_session *session, char *url)
1854 return send_command(session, AST_FRAME_HTML, AST_HTML_URL, 0,
1855 (unsigned char *)url, (int)strlen(url), -1);
1858 int iax_ring_announce(struct iax_session *session)
1860 return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_RINGING, 0, NULL, 0, -1);
1863 int iax_lag_request(struct iax_session *session)
1865 return send_command(session, AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
1868 int iax_busy(struct iax_session *session)
1870 return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_BUSY, 0, NULL, 0, -1);
1873 int iax_congestion(struct iax_session *session)
1875 return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_CONGESTION, 0, NULL, 0, -1);
1879 int iax_accept(struct iax_session *session, int format)
1881 struct iax_ie_data ied;
1882 memset(&ied, 0, sizeof(ied));
1883 iax_ie_append_int(&ied, IAX_IE_FORMAT, format);
1884 return send_command(session, AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied.buf, ied.pos, -1);
1887 int iax_answer(struct iax_session *session)
1889 return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
1892 int iax_load_complete(struct iax_session *session)
1894 return send_command(session, AST_FRAME_HTML, AST_HTML_LDCOMPLETE, 0, NULL, 0, -1);
1897 int iax_send_url(struct iax_session *session, const char *url, int link)
1899 return send_command(session, AST_FRAME_HTML,
1900 link ? AST_HTML_LINKURL : AST_HTML_URL, 0,
1901 (unsigned char *)url, (int)strlen(url), -1);
1904 int iax_send_text(struct iax_session *session, const char *text)
1906 return send_command(session, AST_FRAME_TEXT, 0, 0,
1907 (unsigned char *)text, (int)strlen(text) + 1, -1);
1910 int iax_send_unlink(struct iax_session *session)
1912 return send_command(session, AST_FRAME_HTML, AST_HTML_UNLINK, 0, NULL, 0, -1);
1915 int iax_send_link_reject(struct iax_session *session)
1917 return send_command(session, AST_FRAME_HTML, AST_HTML_LINKREJECT, 0, NULL, 0, -1);
1920 static int iax_send_pong(struct iax_session *session, unsigned int ts)
1922 struct iax_ie_data ied;
1925 memset(&ied, 0, sizeof(ied));
1927 jb_getinfo(session->jb, &stats);
1929 iax_ie_append_int(&ied,IAX_IE_RR_JITTER, stats.jitter);
1930 /* XXX: should be short-term loss pct.. */
1931 if(stats.frames_in == 0) stats.frames_in = 1;
1932 iax_ie_append_int(&ied,IAX_IE_RR_LOSS,
1933 ((0xff & (stats.losspct/1000)) << 24 |
1934 (stats.frames_lost & 0x00ffffff)));
1935 iax_ie_append_int(&ied,IAX_IE_RR_PKTS, stats.frames_in);
1936 iax_ie_append_short(&ied,IAX_IE_RR_DELAY,
1937 (unsigned short)(stats.current - stats.min));
1938 iax_ie_append_int(&ied,IAX_IE_RR_DROPPED, stats.frames_dropped);
1939 iax_ie_append_int(&ied,IAX_IE_RR_OOO, stats.frames_ooo);
1941 return send_command(session, AST_FRAME_IAX, IAX_COMMAND_PONG, ts, ied.buf, ied.pos, -1);
1944 /* external API; deprecated since we send pings ourselves now (finally) */
1945 int iax_send_ping(struct iax_session *session)
1947 return send_command(session, AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
1950 /* scheduled ping sender; sends ping, then reschedules */
1951 static void send_ping(void *s)
1953 struct iax_session *session = (struct iax_session *)s;
1955 /* important, eh? */
1956 if(!iax_session_valid(session)) return;
1958 send_command(session, AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
1959 session->pingid = iax_sched_add(NULL,NULL, send_ping, (void *)session, ping_time * 1000);
1963 static int iax_send_lagrp(struct iax_session *session, unsigned int ts)
1965 return send_command(session, AST_FRAME_IAX, IAX_COMMAND_LAGRP, ts, NULL, 0, -1);
1968 static int iax_send_txcnt(struct iax_session *session)
1970 struct iax_ie_data ied;
1971 memset(&ied, 0, sizeof(ied));
1972 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, session->transferid);
1973 return send_command_transfer(session, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
1976 static int iax_send_txrej(struct iax_session *session)
1978 struct iax_ie_data ied;
1979 memset(&ied, 0, sizeof(ied));
1980 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, session->transferid);
1981 return send_command_transfer(session, AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, ied.buf, ied.pos);
1984 static int iax_send_txaccept(struct iax_session *session)
1986 struct iax_ie_data ied;
1987 memset(&ied, 0, sizeof(ied));
1988 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, session->transferid);
1989 return send_command_transfer(session, AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, ied.buf, ied.pos);
1992 static int iax_send_txready(struct iax_session *session)
1994 struct iax_ie_data ied;
1995 memset(&ied, 0, sizeof(ied));
1996 /* see asterisk chan_iax2.c */
1997 iax_ie_append_short(&ied, IAX_IE_CALLNO, session->callno);
1998 return send_command(session, AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied.buf, ied.pos, -1);
2001 int iax_auth_reply(struct iax_session *session, char *password, char *challenge, int methods)
2004 struct MD5Context md5;
2005 char realreply[256];
2006 struct iax_ie_data ied;
2007 memset(&ied, 0, sizeof(ied));
2008 if ((methods & IAX_AUTH_MD5) && challenge) {
2010 MD5Update(&md5, (const unsigned char *) challenge,
2011 (unsigned int)strlen(challenge));
2012 MD5Update(&md5, (const unsigned char *) password,
2013 (unsigned int)strlen(password));
2014 MD5Final((unsigned char *) reply, &md5);
2015 memset(realreply, 0, sizeof(realreply));
2016 convert_reply(realreply, (unsigned char *) reply);
2017 iax_ie_append_str(&ied, IAX_IE_MD5_RESULT, realreply);
2019 iax_ie_append_str(&ied, IAX_IE_PASSWORD, password);
2021 return send_command(session, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
2024 static int iax_regauth_reply(struct iax_session *session, char *password, char *challenge, int methods)
2027 struct MD5Context md5;
2028 char realreply[256];
2029 struct iax_ie_data ied;
2030 memset(&ied, 0, sizeof(ied));
2031 iax_ie_append_str(&ied, IAX_IE_USERNAME, session->username);
2032 if ((methods & IAX_AUTHMETHOD_MD5) && challenge) {
2034 MD5Update(&md5, (const unsigned char *) challenge,
2035 (unsigned int)strlen(challenge));
2036 MD5Update(&md5, (const unsigned char *) password,
2037 (unsigned int)strlen(password));
2038 MD5Final((unsigned char *) reply, &md5);
2039 memset(realreply, 0, sizeof(realreply));
2040 convert_reply(realreply, (unsigned char *) reply);
2041 iax_ie_append_str(&ied, IAX_IE_MD5_RESULT, realreply);
2043 iax_ie_append_str(&ied, IAX_IE_PASSWORD, password);
2045 if (strlen(session->unregreason)) { /* Non-zero unregreason length indicates REGREL */
2046 iax_ie_append_str(&ied, IAX_IE_CAUSE, session->unregreason);
2047 return send_command(session, AST_FRAME_IAX, IAX_COMMAND_REGREL, 0, ied.buf, ied.pos, -1);
2049 iax_ie_append_short(&ied, IAX_IE_REFRESH, session->refresh);
2050 return send_command(session, AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
2055 int iax_dial(struct iax_session *session, char *number)
2057 struct iax_ie_data ied;
2058 memset(&ied, 0, sizeof(ied));
2059 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, number);
2060 return send_command(session, AST_FRAME_IAX, IAX_COMMAND_DIAL, 0, ied.buf, ied.pos, -1);
2063 int iax_quelch(struct iax_session *session)
2065 return send_command(session, AST_FRAME_IAX, IAX_COMMAND_QUELCH, 0, NULL, 0, -1);
2068 int iax_unquelch(struct iax_session *session)
2070 return send_command(session, AST_FRAME_IAX, IAX_COMMAND_UNQUELCH, 0, NULL, 0, -1);
2073 int iax_dialplan_request(struct iax_session *session, char *number)
2075 struct iax_ie_data ied;
2076 memset(&ied, 0, sizeof(ied));
2077 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, number);
2078 return send_command(session, AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
2081 static inline int which_bit(unsigned int i)
2084 for(x = 0; x < 32; x++) {
2085 if ((1U << x) == i) {
2092 char iax_pref_codec_add(struct iax_session *session, unsigned int format)
2094 int diff = (int) 'A';
2095 session->codec_order[session->codec_order_len++] = (which_bit(format)) + diff;
2096 session->codec_order[session->codec_order_len] = '\0';
2097 return session->codec_order[session->codec_order_len-1];
2101 void iax_pref_codec_del(struct iax_session *session, unsigned int format)
2103 int diff = (int) 'A';
2106 char remove = which_bit(format) + diff;
2108 strncpy(old, session->codec_order, sizeof(old));
2109 session->codec_order_len = 0;
2111 for (x = 0; x < (int) strlen(old); x++) {
2112 if (old[x] != remove) {
2113 session->codec_order[session->codec_order_len++] = old[x];
2116 session->codec_order[session->codec_order_len] = '\0';
2119 int iax_pref_codec_get(struct iax_session *session, unsigned int *array, int len)
2121 int diff = (int) 'A';
2124 for (x = 0; x < session->codec_order_len && x < len; x++) {
2125 array[x] = (1 << (session->codec_order[x] - diff - 1));
2131 int iax_call(struct iax_session *session, const char *cidnum, const char *cidname, const char *ich, const char *lang, int wait, int formats, int capabilities)
2134 char *part1, *part2;
2137 char *username, *hostname, *secret, *context, *exten, *dnid;
2138 struct iax_ie_data ied;
2140 /* We start by parsing up the temporary variable which is of the form of:
2141 [user@]peer[:portno][/exten[@context]] */
2143 IAXERROR "Invalid IAX Call Handle\n");
2144 DEBU(G "Invalid IAX Call Handle\n");
2147 memset(&ied, 0, sizeof(ied));
2148 strncpy(tmp, ich, sizeof(tmp) - 1);
2149 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
2151 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, cidnum);
2153 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, cidname);
2155 if (session->codec_order_len) {
2156 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, session->codec_order);
2159 session->capability = capabilities;
2160 session->pingid = iax_sched_add(NULL,NULL, send_ping, (void *)session, 2 * 1000);
2162 /* XXX We should have a preferred format XXX */
2163 iax_ie_append_int(&ied, IAX_IE_FORMAT, formats);
2164 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, capabilities);
2166 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, lang);
2168 /* Part 1 is [user[:password]@]peer[:port] */
2169 part1 = strtok(tmp, "/");
2171 /* Part 2 is exten[@context] if it is anything all */
2172 part2 = strtok(NULL, "/");
2174 if (strchr(part1, '@')) {
2175 username = strtok(part1, "@");
2176 hostname = strtok(NULL, "@");
2182 if (username && strchr(username, ':')) {
2183 username = strtok(username, ":");
2184 secret = strtok(NULL, ":");
2189 strncpy(session->username, username, sizeof(session->username) - 1);
2192 strncpy(session->secret, secret, sizeof(session->secret) - 1);
2194 if (strchr(hostname, ':')) {
2195 strtok(hostname, ":");
2196 portno = atoi(strtok(NULL, ":"));
2198 portno = IAX_DEFAULT_PORTNO;
2201 exten = strtok(part2, "@");
2203 context = strtok(NULL, "@");
2210 iax_ie_append_str(&ied, IAX_IE_USERNAME, username);
2211 if (exten && strlen(exten))
2212 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, exten);
2213 if (dnid && strlen(dnid))
2214 iax_ie_append_str(&ied, IAX_IE_DNID, dnid);
2215 if (context && strlen(context))
2216 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
2218 /* Setup host connection */
2219 hp = gethostbyname(hostname);
2221 snprintf(iax_errstr, sizeof(iax_errstr), "Invalid hostname: %s", hostname);
2224 memcpy(&session->peeraddr.sin_addr, hp->h_addr, sizeof(session->peeraddr.sin_addr));
2225 session->peeraddr.sin_port = htons(portno);
2226 session->peeraddr.sin_family = AF_INET;
2227 res = send_command(session, AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
2231 DEBU(G "Waiting not yet implemented\n");
2237 static int calc_rxstamp(struct iax_session *session)
2242 if (!session->rxcore.tv_sec && !session->rxcore.tv_usec) {
2243 session->rxcore = iax_tvnow();
2247 ms = (tv.tv_sec - session->rxcore.tv_sec) * 1000 +
2248 (tv.tv_usec - session->rxcore.tv_usec) / 1000;
2253 static int match(struct sockaddr_in *sin, short callno, short dcallno, struct iax_session *cur)
2255 if ((cur->peeraddr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
2256 (cur->peeraddr.sin_port == sin->sin_port)) {
2257 /* This is the main host */
2258 if ((cur->peercallno == callno) ||
2259 ((dcallno == cur->callno) && !cur->peercallno)) {
2260 /* That's us. Be sure we keep track of the peer call number */
2261 cur->peercallno = callno;
2265 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
2266 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
2267 /* We're transferring */
2268 if (dcallno == cur->callno)
2275 /* splitted match into 2 passes otherwise causing problem of matching
2276 up the wrong session using the dcallno and the peercallno because
2277 during a transfer (2 IAX channels on the same client/system) the
2278 same peercallno (from two different asterisks) exist in more than
2281 static int forward_match(struct sockaddr_in *sin, short callno, short dcallno, struct iax_session *cur)
2283 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
2284 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
2285 /* We're transferring */
2286 if (dcallno == cur->callno)
2292 if ((cur->peeraddr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
2293 (cur->peeraddr.sin_port == sin->sin_port)) {
2294 if (dcallno == cur->callno && dcallno != 0) {
2295 /* That's us. Be sure we keep track of the peer call number */
2296 if (cur->peercallno == 0) {
2297 cur->peercallno = callno;
2299 else if ( cur->peercallno != callno )
2301 // print a warning when the callno's don't match
2302 fprintf( stderr, "WARNING: peercallno does not match callno"
2303 ", peercallno => %d, callno => %d, dcallno => %d",
2304 cur->peercallno, callno, dcallno ) ;
2314 static int reverse_match(struct sockaddr_in *sin, short callno, struct iax_session *cur)
2316 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
2317 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
2318 /* We're transferring */
2319 if (callno == cur->peercallno) {
2323 if ((cur->peeraddr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
2324 (cur->peeraddr.sin_port == sin->sin_port)) {
2325 if (callno == cur->peercallno) {
2333 static struct iax_session *iax_find_session(struct sockaddr_in *sin,
2338 struct iax_session *cur = sessions;
2340 if (forward_match(sin, callno, dcallno, cur)) {
2348 if (reverse_match(sin, callno, cur)) {
2354 if (makenew && !dcallno) {
2355 cur = iax_session_new();
2356 cur->peercallno = callno;
2357 cur->peeraddr.sin_addr.s_addr = sin->sin_addr.s_addr;
2358 cur->peeraddr.sin_port = sin->sin_port;
2359 cur->peeraddr.sin_family = AF_INET;
2360 cur->pingid = iax_sched_add(NULL,NULL, send_ping, (void *)cur, 2 * 1000);
2361 DEBU(G "Making new session, peer callno %d, our callno %d\n", callno, cur->callno);
2363 DEBU(G "No session, peer = %d, us = %d\n", callno, dcallno);
2368 #ifdef EXTREME_DEBUG
2369 static int display_time(int ms)
2371 static int oldms = -1;
2373 DEBU(G "First measure\n");
2377 DEBU(G "Time from last frame is %d ms\n", ms - oldms);
2383 /* From chan_iax2/steve davies: need to get permission from steve or digium, I guess */
2384 static long unwrap_timestamp(long ts, long last)
2388 if ( (ts & 0xFFFF0000) == (last & 0xFFFF0000) ) {
2391 /* Sudden big jump backwards in timestamp:
2392 What likely happened here is that miniframe
2393 timestamp has circled but we haven't gotten the
2394 update from the main packet. We'll just pretend
2395 that we did, and update the timestamp
2397 ts = ( (last & 0xFFFF0000) + 0x10000) | (ts & 0xFFFF);
2398 DEBU(G "schedule_delivery: pushed forward timestamp\n");
2401 /* Sudden apparent big jump forwards in timestamp:
2402 What's likely happened is this is an old miniframe
2403 belonging to the previous top-16-bit timestamp that
2404 has turned up out of order. Adjust the timestamp
2406 ts = ( (last & 0xFFFF0000) - 0x10000) | (ts & 0xFFFF);
2407 DEBU(G "schedule_delivery: pushed back timestamp\n");
2410 else if ( (ts & 0xFFFF8000L) == (last & 0xFFFF8000L) ) {
2413 /* Sudden big jump backwards in timestamp:
2414 What likely happened here is that miniframe
2415 timestamp has circled but we haven't gotten the
2416 update from the main packet. We'll just pretend
2417 that we did, and update the timestamp
2419 ts = ( (last & 0xFFFF8000L) + 0x10000) | (ts & 0xFFFF);
2420 DEBU(G "schedule_delivery: pushed forward timestamp\n");
2423 /* Sudden apparent big jump forwards in timestamp:
2424 * What's likely happened is this is an old miniframe
2425 * belonging to the previous top-16-bit timestamp that
2426 * has turned up out of order. Adjust the timestamp
2428 ts = ( (last & 0xFFFF8000L) - 0x10000) | (ts & 0xFFFF);
2429 DEBU(G "schedule_delivery: pushed back timestamp\n");
2436 static struct iax_event *schedule_delivery(struct iax_event *e, unsigned int ts, int updatehistory)
2439 * This is the core of the IAX jitterbuffer delivery mechanism:
2440 * Dynamically adjust the jitterbuffer and decide how long to wait
2441 * before delivering the packet.
2444 #ifdef EXTREME_DEBUG
2445 DEBU(G "[%p] We are at %d, packet is for %d\n", e->session, calc_rxstamp(e->session), ts);
2448 /* insert into jitterbuffer */
2449 /* TODO: Perhaps we could act immediately if it's not droppable and late */
2450 if ( !iax_use_jitterbuffer ||
2451 (e->etype == IAX_EVENT_VIDEO &&
2452 video_bypass_jitterbuffer) )
2454 iax_sched_add(e, NULL, NULL, NULL, 0);
2458 int type = JB_TYPE_CONTROL;
2461 if(e->etype == IAX_EVENT_VOICE)
2463 type = JB_TYPE_VOICE;
2464 /* The frame time only has an effect for voice */
2465 len = get_sample_cnt(e) / 8;
2466 } else if(e->etype == IAX_EVENT_VIDEO)
2468 type = JB_TYPE_VIDEO;
2469 } else if(e->etype == IAX_EVENT_CNG)
2471 type = JB_TYPE_SILENCE;
2474 /* unwrap timestamp */
2475 ts = unwrap_timestamp(ts,e->session->last_ts);
2477 /* move forward last_ts if it's greater. We do this _after_
2478 * unwrapping, because asterisk _still_ has cases where it
2479 * doesn't send full frames when it ought to */
2480 if(ts > e->session->last_ts)
2482 e->session->last_ts = ts;
2485 if(jb_put(e->session->jb, e, type, len, ts,
2486 calc_rxstamp(e->session)) == JB_DROP)
2495 static int uncompress_subclass(unsigned char csub)
2497 /* If the SC_LOG flag is set, return 2^csub otherwise csub */
2498 if (csub & IAX_FLAG_SC_LOG)
2499 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
2504 static void iax_handle_vnak(struct iax_session *session, struct ast_iax2_full_hdr *fh)
2506 struct iax_sched *sch, *list, *l, *tmp;
2509 * According to the IAX2 02 draft, we MUST immediately retransmit all frames
2510 * with higher sequence number than the VNAK's iseqno
2511 * However, it seems that the right thing to do would be to retransmit
2512 * frames with sequence numbers higher OR EQUAL to VNAK's iseqno.
2516 while ( sch != NULL )
2518 if ( sch->frame != NULL &&
2519 sch->frame->session == session
2523 * We want to check if our frame's oseqno is greater or equal than
2524 * the VNAK's iseqno, but we need to take into account sequence
2525 * number wrap-arounds
2526 * session->rseqno is our last acknowledged sequence number, so
2527 * we use that as a base
2529 if ( (unsigned char)(fh->iseqno - session->rseqno) <= (unsigned char)(sch->frame->oseqno - session->rseqno) )
2532 * We cannot retransmit immediately, since the frames are ordered by retransmit time
2533 * We need to collect them and orrange them in ascending order of their oseqno
2535 tmp = (struct iax_sched *)calloc(1, sizeof(struct iax_sched));
2536 tmp->frame = sch->frame;
2538 if ( list == NULL ||
2539 (list->frame->oseqno - session->rseqno) > (tmp->frame->oseqno - session->rseqno)
2549 if ( l->next == NULL ||
2550 (l->next->frame->oseqno - session->rseqno) > (tmp->frame->oseqno - session->rseqno)
2553 tmp->next = l->next;
2565 /* Transmit collected frames and free the space */
2566 while ( list != NULL )
2569 iax_xmit_frame(tmp->frame);
2575 static struct iax_event *iax_header_to_event(struct iax_session *session, struct ast_iax2_full_hdr *fh, int datalen, struct sockaddr_in *sin)
2577 struct iax_event *e;
2578 struct iax_sched *sch;
2582 int updatehistory = 1;
2585 if (fh->type==AST_FRAME_VIDEO)
2586 subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
2588 subclass = uncompress_subclass(fh->csub);
2590 /* don't run last_ts backwards; i.e. for retransmits and the like */
2591 if (ts > session->last_ts &&
2592 (fh->type == AST_FRAME_IAX &&
2593 subclass != IAX_COMMAND_ACK &&
2594 subclass != IAX_COMMAND_PONG &&
2595 subclass != IAX_COMMAND_LAGRP))
2597 session->last_ts = ts;
2600 #ifdef DEBUG_SUPPORT
2602 iax_showframe(NULL, fh, 1, sin, datalen);
2605 /* Get things going with it, timestamp wise, if we
2608 /* Handle implicit ACKing unless this is an INVAL, and only if this is
2609 from the real peer, not the transfer peer */
2610 if ( !inaddrcmp(sin, &session->peeraddr) &&
2611 ( subclass != IAX_COMMAND_INVAL ||
2612 fh->type != AST_FRAME_IAX
2617 /* XXX This code is not very efficient. Surely there is a better way which still
2618 properly handles boundary conditions? XXX */
2619 /* First we have to qualify that the ACKed value is within our window */
2620 for (x=session->rseqno; x != session->oseqno; x++)
2621 if (fh->iseqno == x)
2623 if ((x != session->oseqno) || (session->oseqno == fh->iseqno))
2625 /* The acknowledgement is within our window. Time to acknowledge everything
2627 for (x=session->rseqno; x != fh->iseqno; x++)
2629 /* Ack the packet with the given timestamp */
2630 DEBU(G "Cancelling transmission of packet %d\n", x);
2635 sch->frame->session == session &&
2636 sch->frame->oseqno == x
2638 sch->frame->retries = -1;
2642 /* Note how much we've received acknowledgement for */
2643 session->rseqno = fh->iseqno;
2645 DEBU(G "Received iseqno %d not within window %d->%d\n", fh->iseqno, session->rseqno, session->oseqno);
2648 /* Check where we are */
2649 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
2650 ((fh->type != AST_FRAME_VOICE) && (fh->type != AST_FRAME_VIDEO)))
2652 if ((session->iseqno != fh->oseqno) &&
2654 ((subclass != IAX_COMMAND_TXREADY) &&
2655 (subclass != IAX_COMMAND_TXREL) &&
2656 (subclass != IAX_COMMAND_TXCNT) &&
2657 (subclass != IAX_COMMAND_TXACC)) ||
2658 (fh->type != AST_FRAME_IAX)))
2661 ((subclass != IAX_COMMAND_ACK) &&
2662 (subclass != IAX_COMMAND_INVAL) &&
2663 (subclass != IAX_COMMAND_TXREADY) &&
2664 (subclass != IAX_COMMAND_TXREL) &&
2665 (subclass != IAX_COMMAND_TXCNT) &&
2666 (subclass != IAX_COMMAND_TXACC) &&
2667 (subclass != IAX_COMMAND_VNAK)) ||
2668 (fh->type != AST_FRAME_IAX))
2670 /* If it's not an ACK packet, it's out of order. */
2671 DEBU(G "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
2672 session->iseqno, fh->oseqno, fh->type, subclass);
2675 * Check if session->iseqno > fh->oseqno, accounting for possible wrap around
2676 * This is correct if the two values are not equal (which, in this case, is guaranteed)
2678 if ( (unsigned char)(session->iseqno - fh->oseqno) < 128 )
2680 /* If we've already seen it, ack it XXX There's a border condition here XXX */
2681 if ((fh->type != AST_FRAME_IAX) ||
2682 ((subclass != IAX_COMMAND_ACK) && (subclass != IAX_COMMAND_INVAL)))
2684 DEBU(G "Acking anyway\n");
2685 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
2686 we have anything to send, we'll retransmit and get an ACK back anyway XXX */
2687 send_command_immediate(session, AST_FRAME_IAX, IAX_COMMAND_ACK, ts, NULL, 0,fh->iseqno);
2691 /* Send a VNAK requesting retransmission */
2698 /* Increment unless it's an ACK or VNAK */
2699 if (((subclass != IAX_COMMAND_ACK) &&
2700 (subclass != IAX_COMMAND_INVAL) &&
2701 (subclass != IAX_COMMAND_TXCNT) &&
2702 (subclass != IAX_COMMAND_TXACC) &&
2703 (subclass != IAX_COMMAND_VNAK)) ||
2704 (fh->type != AST_FRAME_IAX))
2708 e = (struct iax_event *)malloc(sizeof(struct iax_event) + datalen + 1);
2711 memset(e, 0, sizeof(struct iax_event) + datalen);
2712 /* Set etype to some unknown value so do not inavertently
2713 sending IAX_EVENT_CONNECT event, which is 0 to application.
2716 e->session = session;
2718 case AST_FRAME_DTMF:
2719 e->etype = IAX_EVENT_DTMF;
2720 e->subclass = subclass;
2722 We want the DTMF event deliver immediately so all I/O can be
2723 terminate quickly in an IVR system.
2724 e = schedule_delivery(e, ts, updatehistory); */
2726 case AST_FRAME_VOICE:
2727 e->etype = IAX_EVENT_VOICE;
2728 e->subclass = subclass;
2730 session->voiceformat = subclass;
2732 memcpy(e->data, fh->iedata, datalen);
2733 e->datalen = datalen;
2735 e = schedule_delivery(e, ts, updatehistory);
2738 e->etype = IAX_EVENT_CNG;
2739 e->subclass = subclass;
2741 memcpy(e->data, fh->iedata, datalen);
2742 e->datalen = datalen;
2744 e = schedule_delivery(e, ts, updatehistory);
2749 memcpy(e->data, fh->iedata, datalen);
2750 e->datalen = datalen;
2752 if (iax_parse_ies(&e->ies, e->data, e->datalen)) {
2753 IAXERROR "Unable to parse IE's");
2759 case IAX_COMMAND_NEW:
2760 /* This is a new, incoming call */
2761 /* save the capability for validation */
2762 session->capability = e->ies.capability;
2763 if (e->ies.codec_prefs) {
2764 strncpy(session->codec_order,
2766 sizeof(session->codec_order));
2767 session->codec_order_len =
2768 (int)strlen(session->codec_order);
2770 e->etype = IAX_EVENT_CONNECT;
2771 e = schedule_delivery(e, ts, updatehistory);
2773 case IAX_COMMAND_AUTHREQ:
2774 /* This is a request for a call */
2775 e->etype = IAX_EVENT_AUTHRQ;
2776 if (strlen(session->username) && !strcmp(e->ies.username, session->username) &&
2777 strlen(session->secret)) {
2778 /* Hey, we already know this one */
2779 iax_auth_reply(session, session->secret, e->ies.challenge, e->ies.authmethods);
2784 e = schedule_delivery(e, ts, updatehistory);
2786 case IAX_COMMAND_HANGUP:
2787 e->etype = IAX_EVENT_HANGUP;
2788 e = schedule_delivery(e, ts, updatehistory);
2790 case IAX_COMMAND_INVAL:
2791 e->etype = IAX_EVENT_HANGUP;
2792 e = schedule_delivery(e, ts, updatehistory);
2794 case IAX_COMMAND_REJECT:
2795 e->etype = IAX_EVENT_REJECT;
2796 e = schedule_delivery(e, ts, updatehistory);
2798 case IAX_COMMAND_ACK:
2802 case IAX_COMMAND_VNAK:
2803 iax_handle_vnak(session, fh);
2807 case IAX_COMMAND_LAGRQ:
2808 /* Pass this along for later handling */
2809 e->etype = IAX_EVENT_LAGRQ;
2811 e = schedule_delivery(e, ts, updatehistory);
2813 case IAX_COMMAND_POKE:
2814 e->etype = IAX_EVENT_POKE;
2817 case IAX_COMMAND_PING:
2818 /* PINGS and PONGS don't get scheduled; */
2819 e->etype = IAX_EVENT_PING;
2822 case IAX_COMMAND_PONG:
2823 e->etype = IAX_EVENT_PONG;
2824 /* track weighted average of ping time */
2825 session->pingtime = ((2 * session->pingtime) + (calc_timestamp(session,0,NULL) - ts)) / 3;
2826 session->remote_netstats.jitter = e->ies.rr_jitter;
2827 session->remote_netstats.losspct = e->ies.rr_loss >> 24;;
2828 session->remote_netstats.losscnt = e->ies.rr_loss & 0xffffff;
2829 session->remote_netstats.packets = e->ies.rr_pkts;
2830 session->remote_netstats.delay = e->ies.rr_delay;
2831 session->remote_netstats.dropped = e->ies.rr_dropped;
2832 session->remote_netstats.ooo = e->ies.rr_ooo;
2834 case IAX_COMMAND_ACCEPT:
2835 if (e->ies.format & session->capability) {
2836 e->etype = IAX_EVENT_ACCEPT;
2839 struct iax_ie_data ied;
2840 /* Although this should not happen, we
2841 * added this to make sure the
2842 * negotiation protocol is enforced.
2843 * For lack of event to notify the
2844 * application we use the defined
2847 memset(&ied, 0, sizeof(ied));
2848 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unable to negotiate codec");
2849 send_command_final(session, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
2850 e->etype = IAX_EVENT_REJECT;
2852 e = schedule_delivery(e, ts, updatehistory);
2854 case IAX_COMMAND_REGACK:
2855 e->etype = IAX_EVENT_REGACK;
2856 e = schedule_delivery(e, ts, updatehistory);
2858 case IAX_COMMAND_REGAUTH:
2859 iax_regauth_reply(session, session->secret, e->ies.challenge, e->ies.authmethods);
2863 case IAX_COMMAND_REGREJ:
2864 e->etype = IAX_EVENT_REGREJ;
2865 e = schedule_delivery(e, ts, updatehistory);
2867 case IAX_COMMAND_LAGRP:
2868 e->etype = IAX_EVENT_LAGRP;
2869 nowts = calc_timestamp(session, 0, NULL);
2871 /* Can't call schedule_delivery since timestamp is non-normal */
2873 case IAX_COMMAND_TXREQ:
2874 /* added check for defensive programming
2875 * - in case the asterisk server
2876 * or another client does not send the
2877 * apparent transfer address
2879 if (e->ies.apparent_addr != NULL) {
2880 /* so a full voice frame is sent on the
2881 next voice output */
2882 session->svoiceformat = -1;
2883 session->transfer = *e->ies.apparent_addr;
2884 session->transfer.sin_family = AF_INET;
2885 session->transfercallno = e->ies.callno;
2886 session->transferring = TRANSFER_BEGIN;
2887 session->transferid = e->ies.transferid;
2888 iax_send_txcnt(session);
2893 case IAX_COMMAND_DPREP:
2894 /* Received dialplan reply */
2895 e->etype = IAX_EVENT_DPREP;
2896 /* Return immediately, makes no sense to schedule */
2898 case IAX_COMMAND_TXCNT:
2899 if (session->transferring) {
2900 session->transfer = *sin;
2901 iax_send_txaccept(session);
2906 case IAX_COMMAND_TXACC:
2907 if (session->transferring) {
2908 stop_transfer(session);
2909 session->transferring = TRANSFER_READY;
2910 iax_send_txready(session);
2915 case IAX_COMMAND_TXREL:
2916 /* Release the transfer */
2917 send_command_immediate(session, AST_FRAME_IAX, IAX_COMMAND_ACK, ts, NULL, 0, fh->iseqno);
2918 if (session->transferring) {
2919 complete_transfer(session, e->ies.callno, 1, 0);
2922 complete_transfer(session, session->peercallno, 0, 1);
2924 e->etype = IAX_EVENT_TRANSFER;
2925 /* notify that asterisk no longer sitting between peers */
2926 e = schedule_delivery(e, ts, updatehistory);
2928 case IAX_COMMAND_QUELCH:
2929 e->etype = IAX_EVENT_QUELCH;
2930 session->quelch = 1;
2932 case IAX_COMMAND_UNQUELCH:
2933 e->etype = IAX_EVENT_UNQUELCH;
2934 session->quelch = 0;
2936 case IAX_COMMAND_TXREJ:
2937 e->etype = IAX_EVENT_TXREJECT;
2938 iax_handle_txreject(session);
2941 case IAX_COMMAND_TXREADY:
2942 send_command_immediate(session, AST_FRAME_IAX, IAX_COMMAND_ACK, ts, NULL, 0, fh->iseqno);
2943 if (iax_handle_txready(session)) {
2944 e->etype = IAX_EVENT_TXREADY;
2952 DEBU(G "Don't know what to do with IAX command %d\n", subclass);
2957 case AST_FRAME_CONTROL:
2959 case AST_CONTROL_ANSWER:
2960 e->etype = IAX_EVENT_ANSWER;
2961 e = schedule_delivery(e, ts, updatehistory);
2963 case AST_CONTROL_CONGESTION:
2964 case AST_CONTROL_BUSY:
2965 e->etype = IAX_EVENT_BUSY;
2966 e = schedule_delivery(e, ts, updatehistory);
2968 case AST_CONTROL_RINGING:
2969 e->etype = IAX_EVENT_RINGA;
2970 e = schedule_delivery(e, ts, updatehistory);
2973 DEBU(G "Don't know what to do with AST control %d\n", subclass);
2978 case AST_FRAME_IMAGE:
2979 e->etype = IAX_EVENT_IMAGE;
2980 e->subclass = subclass;
2982 memcpy(e->data, fh->iedata, datalen);
2984 e = schedule_delivery(e, ts, updatehistory);
2986 case AST_FRAME_VIDEO:
2987 e->etype = IAX_EVENT_VIDEO;
2988 e->subclass = subclass;
2990 session->videoformat = e->subclass;
2991 memcpy(e->data, fh->iedata, datalen);
2992 e->datalen = datalen;
2993 e = schedule_delivery(e, ts, updatehistory);
2995 case AST_FRAME_TEXT:
2996 e->etype = IAX_EVENT_TEXT;
2998 memcpy(e->data, fh->iedata, datalen);
2999 e->datalen = datalen;
3001 e = schedule_delivery(e, ts, updatehistory);
3004 case AST_FRAME_HTML:
3006 case AST_HTML_LINKURL:
3007 e->etype = IAX_EVENT_LINKURL;
3011 e->etype = IAX_EVENT_URL;
3012 e->subclass = fh->csub;
3013 e->datalen = datalen;
3015 memcpy(e->data, fh->iedata, datalen);
3017 e = schedule_delivery(e, ts, updatehistory);
3019 case AST_HTML_LDCOMPLETE:
3020 e->etype = IAX_EVENT_LDCOMPLETE;
3021 e = schedule_delivery(e, ts, updatehistory);
3023 case AST_HTML_UNLINK:
3024 e->etype = IAX_EVENT_UNLINK;
3025 e = schedule_delivery(e, ts, updatehistory);
3027 case AST_HTML_LINKREJECT:
3028 e->etype = IAX_EVENT_LINKREJECT;
3029 e = schedule_delivery(e, ts, updatehistory);
3032 DEBU(G "Don't know how to handle HTML type %d frames\n", fh->csub);
3038 DEBU(G "Don't know what to do with frame type %d\n", fh->type);
3043 DEBU(G "Out of memory\n");
3045 /* Already ack'd iax frames */
3046 if (session->aseqno != session->iseqno) {
3047 send_command_immediate(session, AST_FRAME_IAX, IAX_COMMAND_ACK, ts, NULL, 0, fh->iseqno);
3052 /* Some parts taken from iax_miniheader_to_event and from from chan_iax2.c. We must inform Mark Spencer? */
3053 static struct iax_event *iax_videoheader_to_event(struct iax_session *session,
3054 struct ast_iax2_video_hdr *vh, int datalen)
3056 struct iax_event * e;
3058 if ( session->videoformat <= 0 )
3060 DEBU(G "No last video format received on session %d\n",
3065 e = (struct iax_event *)malloc(sizeof(struct iax_event) + datalen);
3069 DEBU(G "Out of memory\n");
3073 e->etype = IAX_EVENT_VIDEO;
3074 e->session = session;
3075 e->subclass = session->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
3076 e->datalen = datalen;
3077 memcpy(e->data, vh->data, e->datalen);
3078 e->ts = (session->last_ts & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
3080 return schedule_delivery(e, e->ts, 1);
3083 static struct iax_event *iax_miniheader_to_event(struct iax_session *session,
3084 struct ast_iax2_mini_hdr *mh, int datalen)
3086 struct iax_event * e;
3088 if ( session->voiceformat <= 0 )
3090 DEBU(G "No last format received on session %d\n", session->callno);
3094 e = (struct iax_event *)malloc(sizeof(struct iax_event) + datalen);
3098 DEBU(G "Out of memory\n");
3102 e->etype = IAX_EVENT_VOICE;
3103 e->session = session;
3104 e->subclass = session->voiceformat;
3105 e->datalen = datalen;
3106 memcpy(e->data, mh->data, datalen);
3107 e->ts = (session->last_ts & 0xFFFF0000) | ntohs(mh->ts);
3109 return schedule_delivery(e, e->ts, 1);
3112 void iax_destroy(struct iax_session *session)
3114 destroy_session(session);
3117 static struct iax_event *iax_net_read(void)
3119 unsigned char buf[65536];
3121 struct sockaddr_in sin;
3123 struct iax_event *event;
3125 sinlen = sizeof(sin);
3126 res = iax_recvfrom(netfd, (char *)buf, sizeof(buf), 0, (struct sockaddr *) &sin, &sinlen);
3128 #if defined(_WIN32_WCE)
3129 if (WSAGetLastError() != WSAEWOULDBLOCK) {
3130 DEBU(G "Error on read: %d\n", WSAGetLastError());
3131 IAXERROR "Read error on network socket: ???");
3133 #elif defined(WIN32) || defined(_WIN32_WCE)
3134 if (WSAGetLastError() != WSAEWOULDBLOCK) {
3135 DEBU(G "Error on read: %d\n", WSAGetLastError());
3136 IAXERROR "Read error on network socket: %s", strerror(errno));
3139 if (errno != EAGAIN) {
3140 DEBU(G "Error on read: %s\n", strerror(errno));
3141 IAXERROR "Read error on network socket: %s", strerror(errno));
3146 event = iax_net_process(buf, res, &sin);
3147 if ( event == NULL )
3149 // We have received a frame. The corresponding event is queued
3150 // We need to motify the entire stack of calling functions so they
3151 // don't go to sleep thinking there are no more frames to process
3152 // TODO: this is buttugly from a design point of view. Basically we
3153 // change libiax2 behavior to accomodate iaxclient.
3154 // There must be a way to do it better.
3155 event = (struct iax_event *)malloc(sizeof(struct iax_event));
3156 if ( event != NULL ) event->etype = IAX_EVENT_NULL;
3161 static struct iax_session *iax_txcnt_session(struct ast_iax2_full_hdr *fh, int datalen,
3162 struct sockaddr_in *sin, short callno, short dcallno)
3164 int subclass = uncompress_subclass(fh->csub);
3165 unsigned char buf[ 65536 ]; /* allocated on stack with same size as iax_net_read() */
3167 struct iax_session *cur;
3169 if ((fh->type != AST_FRAME_IAX) || (subclass != IAX_COMMAND_TXCNT) || (!datalen)) {
3170 return NULL; /* special handling for TXCNT only */
3172 memcpy(buf, fh->iedata, datalen); /* prepare local buf for iax_parse_ies() */
3174 if (iax_parse_ies(&ies, buf, datalen)) {
3175 return NULL; /* Unable to parse IE's */
3177 if (!ies.transferid) {
3178 return NULL; /* TXCNT without proper IAX_IE_TRANSFERID */
3180 for( cur=sessions; cur; cur=cur->next ) {
3181 if ((cur->transferring) && (cur->transferid == (int) ies.transferid) &&
3182 (cur->callno == dcallno) && (cur->transfercallno == callno)) {
3183 /* We're transferring ---
3184 * skip address/port checking which would fail while
3185 * remote peer behind symmetric NAT, verify
3186 * transferid instead
3188 cur->transfer.sin_addr.s_addr = sin->sin_addr.s_addr; /* setup for further handling */
3189 cur->transfer.sin_port = sin->sin_port;
3196 struct iax_event *iax_net_process(unsigned char *buf, int len, struct sockaddr_in *sin)
3198 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)buf;
3199 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)buf;
3200 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)buf;
3201 struct iax_session *session;
3203 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
3204 /* Full size header */
3205 if ((size_t)len < sizeof(struct ast_iax2_full_hdr)) {
3206 DEBU(G "Short header received from %s\n", inet_ntoa(sin->sin_addr));
3207 IAXERROR "Short header received from %s\n", inet_ntoa(sin->sin_addr));
3210 /* We have a full header, process appropriately */
3211 session = iax_find_session(sin,
3212 ntohs(fh->scallno) & ~IAX_FLAG_FULL,
3213 ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, 1);
3215 session = iax_txcnt_session(fh,
3216 len - sizeof(struct ast_iax2_full_hdr),
3217 sin, ntohs(fh->scallno) & ~IAX_FLAG_FULL,
3218 ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS);
3220 return iax_header_to_event(session, fh, len - sizeof(struct ast_iax2_full_hdr), sin);
3221 DEBU(G "No session?\n");
3224 if ((size_t)len < sizeof(struct ast_iax2_mini_hdr)) {
3225 DEBU(G "Short header received from %s\n", inet_ntoa(sin->sin_addr));
3226 IAXERROR "Short header received from %s\n", inet_ntoa(sin->sin_addr));
3229 /* Miniature, voice frame */
3230 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000))
3232 session = iax_find_session(sin, ntohs(vh->callno) & ~0x8000, 0, 0);
3235 return iax_videoheader_to_event(session, vh,
3236 len - sizeof(struct ast_iax2_video_hdr));
3239 session = iax_find_session(sin, ntohs(fh->scallno), 0, 0);
3241 return iax_miniheader_to_event(session, mh,
3242 len - sizeof(struct ast_iax2_mini_hdr));
3244 DEBU(G "No session?\n");
3249 static struct iax_sched *iax_get_sched(struct timeval tv)
3251 struct iax_sched *cur, *prev=NULL;
3253 /* Check the event schedule first. */
3255 if ((tv.tv_sec > cur->when.tv_sec) ||
3256 ((tv.tv_sec == cur->when.tv_sec) &&
3257 (tv.tv_usec >= cur->when.tv_usec))) {
3258 /* Take it out of the event queue */
3260 prev->next = cur->next;
3271 struct iax_event *iax_get_event(int blocking)
3273 struct iax_event *event;
3274 struct iax_frame *frame;
3276 struct iax_sched *cur;
3277 struct iax_session *session;
3281 while((cur = iax_get_sched(tv)))
3287 /* See if this is an event we need to handle */
3288 event = handle_event(event);
3296 /* It's a frame, transmit it and schedule a retry */
3297 if (frame->retries < 0)
3299 /* It's been acked. No need to send it. Destroy the old
3300 frame. If final, destroy the session. */
3302 destroy_session(frame->session);
3306 } else if (frame->retries == 0)
3308 if (frame->transfer)
3310 /* Send a transfer reject since we weren't able to connect */
3311 iax_send_txrej(frame->session);
3319 /* We haven't been able to get an ACK on this packet. If a
3320 final frame, destroy the session, otherwise, pass up timeout */
3323 destroy_session(frame->session);
3329 event = (struct iax_event *)malloc(sizeof(struct iax_event));
3332 event->etype = IAX_EVENT_TIMEOUT;
3333 event->session = frame->session;
3338 return handle_event(event);
3344 struct ast_iax2_full_hdr *fh;
3345 /* Decrement remaining retries */
3347 /* Multiply next retry time by 4, not above MAX_RETRY_TIME though */
3348 frame->retrytime *= 4;
3349 /* Keep under 1000 ms if this is a transfer packet */
3350 if (!frame->transfer)
3352 if (frame->retrytime > MAX_RETRY_TIME)
3353 frame->retrytime = MAX_RETRY_TIME;
3354 } else if (frame->retrytime > 1000)
3355 frame->retrytime = 1000;
3356 fh = (struct ast_iax2_full_hdr *)(frame->data);
3357 fh->dcallno = htons(IAX_FLAG_RETRANS | frame->dcallno);
3358 iax_xmit_frame(frame);
3359 /* Schedule another retransmission */
3360 DEBU(G "Scheduling retransmission %d\n", frame->retries);
3361 iax_sched_add(NULL, frame, NULL, NULL, frame->retrytime);
3363 } else if (cur->func)
3365 cur->func(cur->arg);
3370 /* get jitterbuffer-scheduled events */
3371 for ( session = sessions; session; session = session->next )
3378 now = (tv.tv_sec - session->rxcore.tv_sec) * 1000 +
3379 (tv.tv_usec - session->rxcore.tv_usec) / 1000;
3381 if ( now <= (next = jb_next(session->jb)) )
3384 /* interp len no longer hardcoded, now determined by get_interp_len */
3385 ret = jb_get(session->jb,&frame,now,get_interp_len(session->voiceformat));
3389 event = (struct iax_event *)frame.data;
3390 event = handle_event(event);
3396 /* create an interpolation frame */
3397 //fprintf(stderr, "Making Interpolation frame\n");
3398 event = (struct iax_event *)malloc(sizeof(struct iax_event));
3400 event->etype = IAX_EVENT_VOICE;
3401 event->subclass = session->voiceformat;
3402 /* XXX: ??? applications probably ignore this anyway */
3404 event->session = session;
3406 event = handle_event(event);
3412 iax_event_free((struct iax_event *)frame.data);
3419 /* shouldn't happen */
3424 /* Now look for networking events */
3426 /* Block until there is data if desired */
3431 FD_SET(netfd, &fds);
3433 nextEventTime = iax_time_to_next_event();
3435 if(nextEventTime < 0) select(netfd + 1, &fds, NULL, NULL, NULL);
3438 struct timeval nextEvent;
3440 nextEvent.tv_sec = nextEventTime / 1000;
3441 nextEvent.tv_usec = (nextEventTime % 1000) * 1000;
3443 select(netfd + 1, &fds, NULL, NULL, &nextEvent);
3447 event = iax_net_read();
3449 return handle_event(event);
3452 struct sockaddr_in iax_get_peer_addr(struct iax_session *session)
3454 return session->peeraddr;
3457 void iax_session_destroy(struct iax_session **session)
3459 destroy_session(*session);
3463 void iax_event_free(struct iax_event *event)
3465 /* We gave the user a chance to play with the session now we need to
3466 * destroy it if you are not calling this function on every event you
3467 * read you are now going to leak sessions as well as events!
3469 switch(event->etype) {
3470 case IAX_EVENT_REJECT:
3471 case IAX_EVENT_HANGUP:
3472 /* Destroy this session -- it's no longer valid */
3473 if (event->session) { /* maybe the user did it already */
3474 destroy_session(event->session);
3481 int iax_get_fd(void)
3483 /* Return our network file descriptor. The client can select on this
3484 * (probably with other things, or can add it to a network add sort
3485 * of gtk_input_add for example */
3489 int iax_quelch_moh(struct iax_session *session, int MOH)
3491 struct iax_ie_data ied; //IE Data Structure (Stuff To Send)
3492 memset(&ied, 0, sizeof(ied));
3494 // You can't quelch the quelched
3495 if (session->quelch == 1)
3499 iax_ie_append(&ied, IAX_IE_MUSICONHOLD);
3500 session->transfer_moh = 1;
3503 return send_command(session, AST_FRAME_IAX, IAX_COMMAND_QUELCH, 0, ied.buf, ied.pos, -1);
3506 struct timeval iax_tvnow(void)
3510 #ifdef HAVE_GETTIMEOFDAY
3511 gettimeofday(&tv, 0);
3512 #elif defined(_MSC_VER)
3513 struct _timeb curSysTime;
3515 _ftime(&curSysTime);
3516 tv.tv_sec = (long)curSysTime.time;
3517 tv.tv_usec = curSysTime.millitm * 1000;
3519 #error no gettimeofday or equivalent available