I’m trying to use XMLRPC (with the Rabbit Code Library http://rabbitlib.sourceforge.net/) on a BL5S220.
My problem is it that although the xmlrpc_callback is triggered every time I attempt to access the server (using a Python client on a PC), the code will often not get a positive value from sock_dataready, and the XML content won’t be read.
If I add a bunch of printfs to isolate where things are going wrong, it “fails” far less often. Of course, if I run that code in “run mode”, there are no stdio writes to slow things down and the fail rate increases again.
I’ve tried moving to sock_stringready (since sock_dataready is deprecated), but that doesn’t help. I’ve looked at the various examples which directly use sock_stringready, but nothing jumps out that would make the xmlrpc code fail.
I’m including the xmlrpc.lib callback code for reference. Successful calls trigger tcp_tick 8 times, and receive their first line of XML content after the 2nd tick. Failed calls trigger tcp_tick 12 times, but never receive any XML content.
Any help/insight you can provide would be greatly appreciated.
_xmlrpc_nodebug int xmlrpc_callback( HttpState* state )
{
auto unsigned char szBuffer[2][512];
auto int i;
auto int iBuffer;
auto char *p;
auto char szDate[40];
auto xml_parser_data xmlparserdata;
auto int iExit;
auto XmlRpcState xmlrpcstate;
#ifdef DEBUG_XMLRPC
log( LOG_DEBUG, "xmlrpc_callback" );
#endif
memset( &xmlrpcstate, 0, sizeof(xmlrpcstate) );
xmlrpcstate.pBufferCurPos = xmlrpcstate.szBuffer;
xml_init_parser( &xmlparserdata, xmlrpc_xmlparse_callback, &xmlrpcstate );
// read the xml request
// because the xml parser supports a two buffer
// system we might as well take advantage of it
// so we only read at most 512 bytes at a time
// alternating between buffer 1 and 2
iBuffer = 0;
iExit = 0;
i = sock_dataready( &state->s );
i = sock_read( &state->s, szBuffer[iBuffer], min(sizeof(szBuffer[0]),i) );
szBuffer[iBuffer][i] = '\0';
while( iExit == 0 )
{
if( xml_append_xml( &xmlparserdata, szBuffer[iBuffer] ) )
{
iBuffer++;
if( iBuffer > 1 ) iBuffer = 0;
for(;;)
{
tcp_tick( &state->s );
i = sock_dataready( &state->s );
if( !xml_parse(&xmlparserdata) && i==0 )
{
iExit = 1;
break;
}
if( i != 0 )
{
i = sock_read( &state->s, szBuffer[iBuffer], min(sizeof(szBuffer[0]),i) );
szBuffer[iBuffer][i] = '\0';
break;
}
}
}
else
{
if( !xml_parse( &xmlparserdata ) ) break;
}
}
// formulate a response message
http_date_str( szDate );
p = szBuffer[0];
p += sprintf( p, "HTTP/1.0 200 OK
" );
p += sprintf( p, "Date: %s
", szDate );
p += sprintf( p, "Content-Type: text/html
" );
p += sprintf( p, "
" );
p += sprintf( p, "" );
p += sprintf( p, "" );
p += sprintf( p, "" );
switch( *xmlrpcstate.pSpec->szFuncSig )
{
case 'S':
p += sprintf( p, "<![CDATA[%s]]>", (char*)xmlrpcstate.pRet );
break;
case 'I':
p += sprintf( p, "%d", (int)xmlrpcstate.pRet );
break;
}
p += sprintf( p, "" );
p += sprintf( p, "" );
p += sprintf( p, "" );
cgi_sendstring( state, szBuffer[0] );
return 0;
}