Marc Vandenhende

Suggestions and feedback on Coldfire Lite, part 2

Discussion created by Marc Vandenhende on Mar 18, 2009
Latest reply on Mar 20, 2009 by Marc Vandenhende

I already made a couple of modifications to ColdFire Lite in the past weeks that I consider improvements, and now I have made a couple more!

 

My current project (which is based on AN3518 by Eric Gregori) uses an HTTP client to download information from the internet and display it on an LCD screen.

 

All of this works fine, unless the HTTP server is off line or the IP address cannot be resolved by the CF Lite DNS client. If this happens, my application hangs in a loop somewhere in the CF Lite operating system.

 

So yesterday I took the time to figure out what was going on and what I could do to fix this. And I have found 2 fixes...

 

The first modification is done in the file dnsclnt.c. It appeared that the dns client always returns an IP addres, no matter wether the address could be resolved or not. Only, the returned IP address appears to be some memory pointer instead of an actual IP address when the URL is false.

I solved this by commenting out the line marked in red below and adding the green line:

 


static  int
dnc_lookup(char * name, struct dns_querys ** cacheentry)
{
   struct dns_querys * dns_entry;
   int      alias;

   /* look through the cache for the passed name */
   for(dns_entry = dns_qs; dns_entry; dns_entry = dns_entry->next)
   {
      if(strcmp(dns_entry->dns_names, name) == 0)
         break;

      if((dns_entry->he.h_name) &&
         (strcmp(dns_entry->he.h_name, name) == 0))
      {
         break;
      }
      for(alias = 0; alias < MAXDNSALIAS; alias++)
      {
         if((dns_entry->alist[alias]) &&
            (strcmp(dns_entry->alist[alias], name) == 0))
               goto found_name;
      }
   }

found_name:

   /* if not found, return error */
   if (dns_entry == NULL)
      return ENP_PARAM;

   /* else, prepare to return entry index */
   if (cacheentry != NULL)
      *cacheentry = dns_entry;

   /* if completed request, return success */
//if (dns_entry->rcode != DNSRC_UNSET)
  if (dns_entry->rcode == DNSRC_OK)  /* MvdH : modification */
      return 0;

   /* incomplete request -- return pending or timed-out status */
   if (dns_entry->tries < dns_trys) /* still trying? */
      return ENP_SEND_PENDING;
   else
      return ENP_TIMEOUT;
}

(code sample based on CF Lite V3.2)

 

On to the second modification.

The second modification is located in the file tcpapi.c. The function m_connect uses a 'while' loop to give the system time to connect to the server. But it will NEVER exit this loop when the system cannot connect to that server. So I commented out that loop (red) and replaced it by another one (green), with a built-in time out of 30 seconds.This time out does require the use of an additional variable tmo to keep track of time.

 


int
m_connect(M_SOCK so, struct sockaddr_in * sin, M_CALLBACK(name))
{
   struct tcpcb * tp;
   int e = 0;
  unsigned long tmo;
:
:
:
:
   if(so->state & SS_NBIO)    /* if socket non-blocking, return now */
   {
      /* Socket may have blocked to connect in tcp_output() and then been
       * set to non-blocking in connect callback - e.g., FTP server does this.
       */
      if(so->state & SS_ISCONNECTED)
         goto rtn;

      /* fall to here if it's really in progress */
      e = so->error = EINPROGRESS;
      goto rtn;
   }
/////////////////////////////////////////////////////////////////////////////////////////////////////
// MvdH : the original version locked the system up when the destination

// doesn't exist
// Modified this to make the connection time out
   tmo = cticks + (30 * TPS);
   do
   {
      if (cticks > tmo) break;
      tk_yield();
   } while (so->state & SS_ISCONNECTING);
/////////////////////////////////////////////////////////////////////////////////////////////////////
/*
   while(so->state & SS_ISCONNECTING)
   {
      tcp_sleep(so); //FSL give time to allow connection to complete
   }
*/
   if(so->state & SS_ISCONNECTED)
      e = 0;
   else
//      e = so->error;
      e = so->error = ETIMEDOUT;

rtn:
   UNLOCK_NET_RESOURCE(NET_RESID);
   return e;
}

(code sample based on CF Lite V3.2)

 

So far everything seems to work fine with these modifications. I have tested it with some false URLs and IP addresses. The false IP address connect attempt times out after 30 seconds; the false URL takes a bit more time but it does time out.

 

I hope this helps...

- Marc

Outcomes