From: Steve K. <st...@st...> - 2004-01-08 00:42:54
|
Steve, Looks like you're working your way down there to the problem. I think the other Steve (Steve Underwood -- so there's three Steves here at least), found a bug related to this already, so you should look at that diff as well. There might be a similar error. This may be obvious, but make sure that you have these included in your sources. (they are in CVS..). Here's the most important parts [this is just part of the diff, so it won't apply; see steveu's original messages: /home/steveu/iaxclient/iaxclient/lib/libiax2/src/iax2-parser.c --- lib/libiax2/src/iax2-parser.c 2003-06-07 04:17:59.000000000 +0800 +++ /home/steveu/iaxclient/iaxclient/lib/libiax2/src/iax2-parser.c 2003-12-27 18:56:20.000000000 +0800 [...] @@ -498,10 +502,17 @@ snprintf(tmp, sizeof(tmp), "Expecting transferid to be %d bytes long but was %d\n", sizeof(unsigned int), len); errorf(tmp); } else ies->transferid = ntohl(*((unsigned int *)(data + 2))); break; + case IAX_IE_DATETIME: + if (len != sizeof(unsigned int)) { + snprintf(tmp, sizeof(tmp), "Expecting date/time to be %d bytes long but was %d\n", sizeof(unsigned int), len); + errorf(tmp); + } else + ies->datetime = ntohl(*((unsigned int *)(data + 2))); + break; default: snprintf(tmp, sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len); errorf(tmp); } diff -rU5 lib/libiax2/src/iax.c /home/steveu/iaxclient/iaxclient/lib/libiax2/src/iax.c --- lib/libiax2/src/iax.c 2003-11-13 07:26:38.000000000 +0800 [...] @@ -1993,11 +1995,15 @@ e->datalen = datalen; } return schedule_delivery(e, ts); case AST_FRAME_IAX: /* Parse IE's */ - if (iax_parse_ies(&e->ies, fh->iedata, datalen)) { + if (datalen) { + memcpy(e->data, fh->iedata, datalen); + e->datalen = datalen; + } + if (iax_parse_ies(&e->ies, e->data, e->datalen)) { IAXERROR "Unable to parse IE's"); free(e); e = NULL; break; } And then this one: --- iax.c.ref 2003-12-27 22:19:51.000000000 +0800 +++ iax.c 2003-12-27 22:20:22.000000000 +0800 @@ -1830,11 +1830,14 @@ if ((ms > -4) || (e->etype != IAX_EVENT_VOICE)) { /* Return the event immediately if it's it's less than 3 milliseconds too late, or if it's not voice (believe me, you don't want to just drop a hangup frame because it's late, or a ping, or some such. That kinda ruins retransmissions too */ - return e; + /* Queue for immediate delivery */ + iax_sched_event(e, NULL, 0); + return NULL; + //return e; } DEBU(G "(not so) Silently dropping a packet (ms = %d)\n", ms); /* Silently discard this as if it were to be delivered */ free(e); return NULL; ======================= Then, if you trace through (Mark's) code, you will see that the behavior you're seeing isn't all that unexpected -- iax_get_event(0) will return null in cases where a) There are no pending "scheduled" events that need handling. - AND - either b) there are no events to read from the network (shouldn't happen if we're calling it as a result of netfd being set in select.) OR c) iax_net_read returns null (probably because iax_net_process returns null, which might be because iax_net_process returns null, which might be because schedule_delivery returns null, etc). d) there was an event read from iax_net_read but the event was "handled" by handle_event. Now, the case (c) is the common case, and this will happen whenever a packet is a bit early, for example -- Actually, looking at steveu's changes to schedule_delivery a bit more, it seems like he made it _never_ return the event at all, but to always queue it up for later processing. And now, I'm not sure that was necessary.. It shouldn't hurt too much, but it means the event won't get processed until the next time we call iax_get_event. The code in iaxc_service_network could probably be cleaned up a bit, but it looks like it should work. The question is where are these events getting lost.. I don't see the problem, but I haven't really done any work with incoming calls (my client doesn't get incoming calls :)). Unfortunately, my guess from looking through this for 30 minutes is that somewhere in iax_header_to_event is your problem. Eventually, you need to end up at line 2019: e = schedule_delivery(e, ts); for this.. And schedule_delivery should do the right thing.. (iax_session_new does clear all of it's memory, so that should rxcore should be clear, for example). schedule_delivery should almost always end up where steveu made that change.. (because ms should almost always be zero, unless the clock ticked in the middle of calc_rxstamp). [ note: the gettimeofday implementation on MSWin is a bit coarse, so the difference may be large there, but it should also be positive if it is ]. So, I'm a bit stumped. I'd put a breakpoint (or a print) around line 2019, and make sure you're getting there when a the NEW command comes in.. -SteveK Steven Sokol wrote: >Here's a real surprise I found: the failure in the iaxClient library >seems to be failing when it calls iax_get_event in the iax2 library. >Here's my understanding of how this is happening: > >1. My Client Starts. >2. It initializes IAX2 passing in all the necessary goodies. >3. It calls iaxc_start_processing_thread() to begin processing. >4. iaxc_processor calls the function iaxc_process_calls >5. iaxc_process_calls call iaxc_service_network >6. iaxc_service_network checks for a waiting event using >select/FD_ISSET >7. If an event is waiting (bit is set on net FD), do_iax_event gets >called. >8. do_iax_event continues to get called until FD bit is not set (no >more events?) >9. do_iax_event gets called one more time to handle anything that may >have been missed? >10. iaxc_service_network returns. >11. iaxc_process_calls handles other functions (pings, audio, >registrations). >12. iaxc_process_calls returns. >13. iaxc_processor sleeps for 5ms. >14. iaxc_processor starts over -> Goto Step 5. > >In steps 7, 8 and 9, the code calls do_iax_event() which in turn gets an >event structure by calling the iax_get_event(0) function in iax.c. The >iax_get_event function appears to process pending messages then gets >events from the network by calling iax_net_read. Iax_net_read in turn >grabs a buffer from the network file descriptor and processes it into an >event structure by calling iax_net_process. Iax_net_process converts >the buffer into either a full sized or mini header. Based on the type >of header it uses one of two methods to transform the data into an event >(either an "event" or a voice frame). > >In theory every time the netfd is set (meaning there is an event >waiting) there should be an event structure to read from the network >(from Asterisk). This is where things (under Win32, at least) seem to >break down. I added some code to alert me when the netfd is signaled >but there is no event returned by the iax_get_event(0) call in >iax_do_event (i.e. the event pointer [e] is null). This seems to happen >from time to time. And for whatever reason, it seems to happen fairly >consistently after a few minutes, causing it to miss call notifications. > >Oddly it does not seem to have any problem with re-registration >acknowledgments. And apparently it does not happen on the connection >to/from IAXtel. Would this mean that my local Asterisk is munging the >messages? I see some debugging code in the libiax code, but I don't >know how to activate a debugger that will respond (nor what if anything >needs to be changed in my build to activate the debugging code). > >Any suggestions would be greatly helpful. I know Michael is looking >forward to a fix for this. I don't know if Dante is still plagued by >this one or not, but it would be great to have the Win32 side of the >library clean and running smooth! > >Thanks, > >Steve Sokol >Sokol & Associates, LLC > >[Where I Think Thins Are Going South] > >static void do_iax_event() { > struct iax_event *e = 0; > int callNo; > > while ( (e = iax_get_event(0))) { > // first, see if this is an event for one of our calls. > callNo = iaxc_find_call_by_session(e->session); > if(callNo >= 0) { > iaxc_handle_network_event(e, callNo); > } else if >#ifndef IAXC_IAX2 > ( e->etype == IAX_EVENT_REGREP ) >#else > ((e->etype == IAX_EVENT_REGACK ) || (e->etype == >IAX_EVENT_REGREJ )) >#endif > { > iaxc_handle_regreply(e); > } else if(e->etype == IAX_EVENT_REGREQ ) { > iaxc_usermsg(IAXC_ERROR, "Registration requested >by someone, but we don't understand!"); > } else if(e->etype == IAX_EVENT_CONNECT) { > > callNo = iaxc_first_free_call(); >.... > > > > > > >------------------------------------------------------- >This SF.net email is sponsored by: Perforce Software. >Perforce is the Fast Software Configuration Management System offering >advanced branching capabilities and atomic changes on 50+ platforms. >Free Eval! http://www.perforce.com/perforce/loadprog.html >_______________________________________________ >Iaxclient-devel mailing list >Iax...@li... >https://lists.sourceforge.net/lists/listinfo/iaxclient-devel > > > |