LWIP netconn_new returns null

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
User avatar
stinkytiger
Posts: 9
Joined: Thu Jun 27, 2013 12:53 am

LWIP netconn_new returns null

Post by stinkytiger »

Hi,

I am trying to send a short message via UDP as a broadcast message. However my call to netconn_new returns a null. I traced it through and it fails in Chibios sys_arch.c line 189 which is the check to see if the mbox is valid.

Code: Select all

int sys_mbox_valid(sys_mbox_t *mbox) {
  return *mbox != SYS_MBOX_NULL;
}


and the *mbox comes from the address of a static variable mbox tcpip.c which is in the lwip code.

Code: Select all

  if (sys_mbox_valid(&mbox)) {
    msg.type = TCPIP_MSG_API;
    msg.msg.apimsg = apimsg;
    sys_mbox_post(&mbox, &msg);
    sys_arch_sem_wait(&apimsg->msg.conn->op_completed, 0);
    return apimsg->msg.err;
  }


So it checks to see if mbox is a valid memory location. As far as I can see mbox is declared in tcpip.c as:

Code: Select all

static sys_mbox_t mbox;


Since mbox is static, should that not automatically make it valid? Eclipse shows mbox as this:

mbox 0x2000702c
*mbox 0x00000000
mb_buffer 0x20000400
mb_top 0x080001b1
mb_wrptr 0x080002e1

I am on an OLIMEX STM32F4-E407.

Any ideas what my error might be?

Warmest regards, Mike.

Code: Select all

/*
 *
 *
 */

#include "ch.h"
#include "hal.h"
#include "chprintf.h"
#include <chstreams.h>
#include <string.h>

#include <lwip/ip_addr.h>
#include <lwip/api.h>
#include <lwip/udp.h>
//#include <lwip/memp.h>
//#include <lwip/arch.h>
//#include <lwip/opt.h>
//#include <lwip/def.h>
//#include <lwip/debug.h>
//#include <lwip/mem.h>
#include <lwip/init.h>
#include "lwipopts.h"
#include "lwipthread.h"

static SerialConfig sc;

#define WOOFIE_UDP_PORT 50000

int main(void)
{

   halInit();
   chSysInit();
    lwip_init();

   sc.speed = 38400;
   sc.cr1 = 0;
   sc.cr2 = USART_CR2_STOP1_BITS | USART_CR2_LINEN;
   sc.cr3 = 0;

   sdStart(&SD6, &sc);
   chprintf((BaseSequentialStream*)&SD6, "Hello World!\n\r");


   //memp_init();
   struct netconn *conn = netconn_new(NETCONN_UDP);
   if(conn == NULL)
   {
     chprintf((BaseSequentialStream*)&SD6, "Connection failed\n\r");
   }
   /*
   netconn_bind(conn, IP_ADDR_ANY, WOOFIE_UDP_PORT);
   struct netbuf *buf = netbuf_new();
   char *msg = "This is the UDP message\n";
   char *data = netbuf_alloc(buf, sizeof(msg));
   MEMCPY(data, msg, sizeof(msg));
   netconn_send(conn, buf);
   netbuf_delete(buf);*/
   

   while(TRUE)
   {
      int i;
      for(i = 100; i < 1000; i += 100)
      {
      palTogglePad(GPIOC, GPIOC_LED);
      chThdSleepMilliseconds(i);
      }
   }

   return 0;
}

User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: LWIP netconn_new returns null

Post by Giovanni »

Hi,

sys_mbox_t is a pointer to a Mailbox object so that static declaration does not make it valid, there is just a NULL pointer in there (which is the "invalid" sys_mbox_t state).

Giovanni
User avatar
stinkytiger
Posts: 9
Joined: Thu Jun 27, 2013 12:53 am

Re: LWIP netconn_new returns null

Post by stinkytiger »

Hi,

You are correct. I made a bit more progress and the thing I needed was to use tcpip_init(). This solved the issue. lwip_init() is called by tcpip_init. I was using UDP so thought that I did not have to use any calls to tcpXXX. But this is not the case. I also think that other users may not observe this issue because tcpip_init is usually called in lwip code when receive buffers are set up. I was trying to do transmit only and hence did not set up a receive buffer. tcpip_init I think sets up the mbox memory piece in the code.

Thanks again for your kind help Giovanni,

Warmest regards, Mike.
User avatar
stinkytiger
Posts: 9
Joined: Thu Jun 27, 2013 12:53 am

Re: LWIP netconn_new returns null

Post by stinkytiger »

Hi,

Made some more progress. I think I am now sending out some UDP messages using this code:

Code: Select all

/*
 *
 *
 */

#include "ch.h"
#include "hal.h"
#include "chprintf.h"
#include <string.h>

#include <lwip/netif.h>
#include <lwip/ip_addr.h>
#include <lwip/tcpip.h>
#include "lwipthread.h"

static SerialConfig sc;

#define WOOFIE_UDP_PORT 50000

int main(void)
{

   halInit();
   chSysInit();

   // Set up the RS232 Link to Minicom on /dev/ttyUSB1
   sc.speed = 38400;
   sc.cr1 = 0;
   sc.cr2 = USART_CR2_STOP1_BITS | USART_CR2_LINEN;
   sc.cr3 = 0;

   sdStart(&SD6, &sc);
   chprintf((BaseSequentialStream*)&SD6, "Hello World!\n\r");

   // Now set up the LWIP thread
   struct ip_addr netmask;
   struct ip_addr address;
   struct ip_addr gateway;
   IP4_ADDR(&address, 192, 168,   1, 44);
   IP4_ADDR(&netmask, 255, 255, 255,  0);
   IP4_ADDR(&gateway, 192, 168,   1,  1);

   static uint8_t macaddrarray[6] = {0x0A,0x0B,0x0C,0x0D,0x0E,0x0F};
   struct lwipthread_opts ip_opts;
   ip_opts.macaddress = macaddrarray;
   ip_opts.netmask    = netmask.addr;
   ip_opts.gateway    = gateway.addr;
   ip_opts.address    = address.addr;

   chprintf((BaseSequentialStream*)&SD6, "Here 1\n\r");

   chThdCreateStatic(wa_lwip_thread, LWIP_THREAD_STACK_SIZE, NORMALPRIO,
                lwip_thread, &ip_opts);

   chprintf((BaseSequentialStream*)&SD6, "Here 2\n\r");

   struct netconn *conn = netconn_new(NETCONN_UDP);
   if(conn == NULL)
   {
     chprintf((BaseSequentialStream*)&SD6, "Connection failed\n\r");
   }

   struct ip_addr addr;
   IP4_ADDR(&addr, 192, 168, 1, 42);
   // addr.addr = htonl(0xC0A8012A);  // 192.168.1.42
   int err = netconn_connect(conn, &addr, WOOFIE_UDP_PORT);
   chprintf((BaseSequentialStream*)&SD6, "Netconn connect %d \n\r", err);
   struct netbuf *buf = netbuf_new();
   static char msg[] = "This is the UDP message\n";
   char *data = netbuf_alloc(buf, sizeof(msg));
   MEMCPY(data, msg, sizeof(msg));
   err = netconn_send(conn, buf);
   chprintf((BaseSequentialStream*)&SD6, "Netconn send %d \n\r", err);
   // netbuf_delete(buf);
   
   int count = 0;
   while(TRUE)
   {
      int i;
      for(i = 100; i < 1000; i += 100)
      {
      palTogglePad(GPIOC, GPIOC_LED);
      chThdSleepMilliseconds(i);
      err = netconn_send(conn, buf);
      chprintf((BaseSequentialStream*)&SD6, "Netconn send %d : %d\n\r", err, count);
      count++;
      }
   }

   return 0;
}




I was running into a chDbgPanic on the lwip_thread. I bumped the LWIP_THREAD_STACK_SIZE from 512 to 1024 and I think that fixed it.

I am getting a return code from the netconn_send(con, buf) of zero. So this means that we are good, no error. I am also seeing the light on the Ethernet switch twinkle and the correct rate. So that is good too. I can ping my Olimex board on 192.168.1.44 and that works.

The issue I am having is that I think I am sending my message on UDP onto Port 50000. So if I listen on my linux box on Port 50000 using netcat linux command like this:

Code: Select all

[papa@calvin2 ~]$ nc -vv -l -u -p 50000
Listening on any address 50000



then I should see "This is the UDP message" appear on the screen. But this does not happen. I think the message is hitting the network because of the Ethernet switch light twinkles. This may be a bit off topic in that the error may be not ChibiOS related, but could be network related. Could my LinkSys router be messing things up?

Any hints / ideas much appreciated as usual.

Warmest regards, Mike.
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: LWIP netconn_new returns null

Post by Giovanni »

Ia your IP address in the same subnet of your router?

Giovanni
User avatar
stinkytiger
Posts: 9
Joined: Thu Jun 27, 2013 12:53 am

Re: LWIP netconn_new returns null

Post by stinkytiger »

Hi,

Success!!! I now see:

    [papa@calvin2 woofie2]$ nc -p 50000 -luvv
    Listening on any address 50000
    Received packet from 192.168.1.44:49153 -> 192.168.1.42:50000 (local)
    ��PK|8E5�8��,��*��P!�This is the UDP message
    ��PK|8E5�8��,��*��P!�This is the UDP message
    ��PK|8E5�8��,��*��P!�This is the UDP message

The issuse I had was that on my Linux box running CentOS, the iptables firewall filtered out the messages. Hence the network is sending but nothing on screen. I fixed the IPTABLES so that it would accept messages from my Olimex board and that fixed it.

Warmest regards, Mike.
Post Reply