Date   

Re: understanding of logic behind address used in Publish-Subscribe mechanism for Bluetooth Mesh

Johan Hedberg
 

Hi Vikrant,

On Sat, Dec 02, 2017, Vikrant More wrote:
unsigned char elem_idx = model->elem->addr - bt_mesh_primary_addr();
What do you need this for? If you need to access the element it's right
there in model->elem.

Data(set)= *0 or 1*
Data(set) unicast_addr = *1*
Data(set) pub_addr = *0xC000 <--------------------------What is
significance of this address ??*
Data(set) sub_addr =

*0XC001 *

*when I control Led individually , source address = 0x2001 & destination
address = 0x0001*

*when I control Led using master control , source address = 0x2001 &
destination address = 0xC001.*

*Then tell me what is roll or use of 0xC000 ?*

*Or how it will help us ?*
That's just some group address the provisioner has apparently configured
this model to publish to.

Johan


GPIO interrupt not linked using zephyr API

Vikrant More <vikrant8051@...>
 

Hello,

//----------------------------------------------------------------------------------------------------------------------------

#include <zephyr.h>
#include <misc/printk.h>

#include "nrf_delay.h"
#include "nrf_gpio.h"

#include "board.h"


#define  SETB(x,y)   (x|=(1<<y))     //for o/p
#define  CLRB(x,y)   (x&=(~(1<<y)))  //for o/p
#define  TGLB(x,y)   (x^=(1<<y))     //for o/p
#define  CHECKB(x,y) (x&(1<<y))      //for i/p

void GPIOTE_IRQHandler(void *arg)
{
  if(NRF_GPIOTE->EVENTS_IN[0]==1)
  {
    NRF_GPIOTE->EVENTS_IN[0]=0;
    NRF_P0->OUT ^= (1<<15); //LED3
  }
}

void gpio_init(void)
{
 
  NRF_P0->DIR |= 0x0001E000;
  NRF_P0->OUTSET |= 0x0001E000;

  NRF_P0->PIN_CNF[11]=0x0000000C;


  NRF_GPIOTE->INTENSET |= 0x00000001;                         
  NRF_GPIOTE->CONFIG[0] |= 0x00000001 | (11<<8) | (2<<16);

  //NVIC_EnableIRQ(GPIOTE_IRQn);

  IRQ_CONNECT(6,1,GPIOTE_IRQHandler,0,0);
  irq_enable(6);
}

void main(void)
{
    printk("Hello World! %s\n", CONFIG_ARCH);
    gpio_init();

    while(1)
    {
        NRF_P0->OUT ^= (1<<13); //LED1
        nrf_delay_ms(20);

        /*(Polling Method)
        if(CHECKB(NRF_P0->IN,11)==0)
        {

            while(CHECKB(NRF_P0->IN,11)==0){} 

            printk("Button Pressed !!\n\r");

            NRF_P0->OUT ^= (1<<16); //LED4

        }
        */
    }
}

//---------------------------------------------------------------------------------------------------------------------------------------

This is my simple code in which I want to enable button pressed interrupt.

My board is nrf52840_pca10056.

Button1 is attached to P0.11.
Using polling method, I'm able to toggle on board LED4. But same is not happing with interrupt.
Code gets compile without any error. But don't know why interrupt is not working.

I've also add following config parameters in prj.conf

CONFIG_GPIO=y
CONFIG_GPIO_NRF5_P0=y
CONFIG_GPIO_NRF5_P0_DEV_NAME="SW0_GPIO_PIN"
CONFIG_GPIO_NRF5_PORT_P0_PRI=6



For reference I'm using this link -> http://docs.zephyrproject.org/kernel/other/interrupts.html


Re: help with building and cmake.

Carles Cufi
 

Hi Graham,

 

The first release after the transition from Make/Kbuild to CMake will be 1.10.

If you are building 1.9.2 then you need to use Make just as you did with  1.7.0. You can generate the documentation for 1.9.2 by running “make htmldocs” from the root of the git repo.

 

Regards,

 

Carles

 

From: <zephyr-users-bounces@...> on behalf of Graham Stott <gbcstott1@...>
Date: Saturday, 2 December 2017 at 05:20
To: "zephyr-users@..." <zephyr-users@...>
Subject: [Zephyr-users] help with building and cmake.

 

I am trying to move my project from zephyr v1.7.0 to v1.9.2. I am using a new Ubuntu 16.04 LTS 64 bit system and therefore I am starting from scratch.

 

I followed the “Getting Started Guide” and first did the “Development Environment setup for Linux”.  I installed cmake version 3.10.0.  I also installed the 0.9.2 SDK.

 

I then follow the “Getting Started Guide” for Building and Running an Application.  In step 4,  it has an example of building the “Hello World” example.  When I enter the following command:

 

cmake –DBOARD=ardino_101 ../..

 

I get  the following error:

 

CMake Error:  “The source directory /home/gstott/zephyr-v1.9.2 /samples/hello_world” does not appear to contain CMakeLists.txt

 

I do not see any instructions on how this file is generated.

 

What am I missing?

 

Graham


understanding of logic behind address used in Publish-Subscribe mechanism for Bluetooth Mesh

Vikrant More <vikrant8051@...>
 

static void gen_onoff_set(struct bt_mesh_model *model,
              struct bt_mesh_msg_ctx *ctx,
              struct net_buf_simple *buf)
{   
   
        static volatile unsigned char copy1=NULL;

        unsigned char elem_idx = model->elem->addr - bt_mesh_primary_addr();

        unsigned char boo = net_buf_simple_pull_u8(buf);

        if( boo != copy1)
        {   
       
         printk("Data(set)= %u \n\r",boo);
         printk("Data(set) unicast_addr = %u \n\r",model->elem->addr);
         printk("Data(set) pub_addr = %u \n\r",model->pub->addr);
         printk("Data(set) sub_addr = %u \n\r",model->groups[0]);
   
         switch(elem_idx)
         {
            case 0:   
                     if(boo!=0)
                        NRF_P0->OUT &= ~(1<<13);
                    
                     else
                        NRF_P0->OUTSET |= (1<<13);                             
                    
                     break;

             case 1:     
                  if(boo!=0)
                     NRF_P0->OUT &= ~(1<<14);
                  else
                     NRF_P0->OUTSET |= (1<<14);                             
                 
                 break;   
          }

          copy1=boo;

       }//end of if

}



I have edited gen_onoff_set function for onoff server as mentioned above.

I'm using Silicon Labs Bluetooth Mesh App to provision & configure my nrf52840_pca10056 Board.


After controlling LED using GUI from App, above function is executing normally.

And it prints ...

Data(set)= 0 or 1
Data(set) unicast_addr = 1
Data(set) pub_addr = 0xC000 <--------------------------What is significance of this address ??
Data(set) sub_addr = 0XC001

when I control Led individually , source address = 0x2001 & destination address = 0x0001

when I control Led using master control , source address = 0x2001 & destination address = 0xC001.

Then tell me what is roll or use of 0xC000 ?
Or how it will help us ?


   

 




help with building and cmake.

Graham Stott <gbcstott1@...>
 

I am trying to move my project from zephyr v1.7.0 to v1.9.2. I am using a new Ubuntu 16.04 LTS 64 bit system and therefore I am starting from scratch.

 

I followed the “Getting Started Guide” and first did the “Development Environment setup for Linux”.  I installed cmake version 3.10.0.  I also installed the 0.9.2 SDK.

 

I then follow the “Getting Started Guide” for Building and Running an Application.  In step 4,  it has an example of building the “Hello World” example.  When I enter the following command:

 

cmake –DBOARD=ardino_101 ../..

 

I get  the following error:

 

CMake Error:  “The source directory /home/gstott/zephyr-v1.9.2 /samples/hello_world” does not appear to contain CMakeLists.txt

 

I do not see any instructions on how this file is generated.

 

What am I missing?

 

Graham


Re: about success rate of publish-subscribe mechanism of Zephyr Bluetooth Mesh

Johan Hedberg
 

Hi Vikrant,

On Fri, Dec 01, 2017, Vikrant More wrote:
if (bt_mesh_model_send(&root_models[2], &ctx1, msg1, NULL, NULL)) {
Note that strictly speaking this isn't publishing. For publishing you'd
use the bt_mesh_model_publish() API. The bt_mesh_model_send() is
primarily intended to be used for responding to messages when you're
implementing a server model.

I am calling this function from Button interrupt
The Mesh APIs aren't designed to be called directly from interrupt
context since they need to potentially block while waiting for buffers
to become available. The encryption procedures also consume a lot of CPU
time, which is unacceptable e.g. for the controller code which relies on
low-latency interrupts. So I'd recommend deferring the calls to thread
context using e.g. k_work, like the mesh_demo app does for the BBC
micro:bit button presses.

But on an average only 6 out 10 times, exact data get received by all
*Subscribers*.

Silicon Labs Bluetooth Mesh App has functionality of *Master Control *(on/off
switch which control LED on all nodes in single click).
It is working perfectly. Success rate is 100%.

But if I try the same with (*Publisher*) node based on Zephyr as mentioned
above then it is not 100% reliable.

Is there anything that I am missing in my code ?
The SiLabs Android app only uses GATT, and GATT is a 100% reliable
bearer. The advertising bearer is not, so you may easily get lost
packets. This is why the Mesh specification comes with all sorts of ways
for fine-tuning transmission reliability. You've e.g. got the Network
Transmit state as well as the Publish Retransmit state that can be used
to increase the number of transmissions that your node does when sending
out data over the advertising bearer.

Johan


about success rate of publish-subscribe mechanism of Zephyr Bluetooth Mesh

Vikrant More <vikrant8051@...>
 

void foo(int a,int b,unsigned char c)
{

    static volatile unsigned char tmp = 0;

    struct net_buf_simple *msg1 = NET_BUF_SIMPLE(2+4+2);

    struct bt_mesh_msg_ctx ctx1 = {
        .net_idx = b,
        .app_idx = a,
        .addr = 0xC001,
        .send_ttl = BT_MESH_TTL_DEFAULT,
    };

   
    bt_mesh_model_msg_init(msg1, BT_MESH_MODEL_OP_2(0x82, 0x03));

    net_buf_simple_add_u8(msg1,c);            // <------------------------------------------------------- C is 0 or 1
    net_buf_simple_add_u8(msg1, 00);    //<-------------------------------------------------------- what to send from here ??
                                                                                                                       // If I didn't add this then firmware throws error after receiving message.

    if (bt_mesh_model_send(&root_models[2], &ctx1, msg1, NULL, NULL)) {
        printk("Unable to send Vendor Button message\n\r");
    }

    printk("Button message sent with OpCode 0x%08x......\n\r", BT_MESH_MODEL_OP_2(0x82, 0x03));

}

I am calling this function from Button interrupt to publish data as '1' or '0' to all nodes which are part
one particular group. But success rate is not impressive at all.

I'm able to see printk("Button message sent with OpCode 0x%08x......\n\r", BT_MESH_MODEL_OP_2(0x82, 0x03)) on
serial terminal of Publisher on each click of button. That means foo() is executing.

But on an average only 6 out 10 times, exact data get received by all Subscribers.

Silicon Labs Bluetooth Mesh App has functionality of Master Control (on/off switch which control LED on all nodes in single click).
It is working perfectly. Success rate is 100%.

But if I try the same with (Publisher) node based on Zephyr as mentioned above then it is not 100% reliable.

Is there anything that I am missing in my code ?

Thank You !!






Re: Discarding Netwok PDU

Johan Hedberg
 

Hi Ashish,

On Fri, Dec 01, 2017, ashish.shukla@corvi.com wrote:
I want to know in the current implementation of mesh, what parameters are
being taken in account to discard a network PDU and not to process it.
There are too many conditions to start listing them here. I recommend
you look at net.c and transport.c under subsys/bluetooth/host/mesh/ and
trace through the code starting with bt_mesh_net_recv() to see what can
cause the packet to be discarded.

The code should be following the specification requirements, so
familiarizing yourself with the Mesh Profile Specification is a good
idea as well.

Also, if I want to process same message from same SRC/DST, what can be done
to process it few times for testing purposes?
If by "same message" you mean the exact same advertising payload, you'll
need to disable at least the duplicate cache, network message cache, and
the replay protection list.

Johan


Discarding Netwok PDU

ashish.shukla@corvi.com <ashish.shukla@...>
 

Hello Everyone !

I want to know in the current implementation of mesh, what parameters are being taken in account to discard a network PDU and not to process it.

Also, if I want to process same message from same SRC/DST, what can be done to process it few times for testing purposes? 

--
Warm regards,
Ashish Shukla
Jr. Embedded Engineer
Research & Development


Please consider the environment before printing this e-mail or its attachments.

Disclaimer: The information contained herein (including any accompanying documents) is confidential and is intended solely for the addressee(s). If you have erroneously received this message, please immediately delete it and notify the sender. Also, if you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution or taking any action in reliance on the contents of this message or any accompanying document is strictly prohibited and is unlawful. The organization is not responsible for any damage caused by a virus or alteration of the e-mail by a third party or otherwise. The contents of this message may not necessarily represent the views or policies of Corvi


Re: Error while publishing from one node to another node in Bluetooth Mesh

Johan Hedberg
 

Hi Vikrant,

On Thu, Nov 30, 2017, Vikrant More wrote:
I am trying to execute above function foo() from Button interrupt on
nRF52840_PCA10056.

And getting error As attached in image.

My intention is to send value of *tmp* variable to all nodes in the Group.
Could you please help me to solve
this error ?
It looks like the sender has been reset without restoring its earlier
state, whereas the receiver has continued running all the time. This
will cause the sender to send using an "old" sequence number, which the
receiver then correctly discards as it's considered to be a message
replay attempt.

Johan


Error while publishing from one node to another node in Bluetooth Mesh

Vikrant More <vikrant8051@...>
 

void foo(int a,int b)
{

    static volatile int tmp = 0;

    struct net_buf_simple *msg1 = NET_BUF_SIMPLE(10);

    struct bt_mesh_msg_ctx ctx1 = {
        .net_idx = b,
        .app_idx = a,
        .addr = 0xFFFE,            // <------------------------------------------------------------------Group Address of all Relay
        .send_ttl = BT_MESH_TTL_DEFAULT,
    };

    
    bt_mesh_model_msg_init(msg1, BT_MESH_MODEL_OP_2(0x82, 0x03));

    net_buf_simple_add_u8(msg1,tmp);
    net_buf_simple_add_u8(msg1,0x00);
    net_buf_simple_add_u8(msg1,0x00);
    net_buf_simple_add_u8(msg1,0x00);

    if (bt_mesh_model_send(&root_models[2], &ctx1, msg1, NULL, NULL))
    {
        printk("Unable to send Vendor Button message\n");
    }

    printk("Button message sent with OpCode 0x%08x\n", BT_MESH_MODEL_OP_2(0x82, 0x03));

    tmp++;

}

I am trying to execute above function foo() from Button interrupt on nRF52840_PCA10056.

And getting error As attached in image.

My intention is to send value of tmp variable to all nodes in the Group. Could you please help me to solve
this error ?



Re: Determining type of device

Boie, Andrew P
 

Hello everyone,


is there a zephyr-way in determining which type a device is, after getting a
reference to it through device_get_binding?

Since a gpio device has the same signature as a flash for example it's not
obvious for me how to make sure that the right device pointer is passed in a
higer-level application.
If you run your threads in user mode, you will get a fatal error if a thread tries to make a driver API system call with the wrong type of driver object.

There is no checking done for threads running in supervisor mode.

Andrew


Re: [Zephyr-devel] RPL Tests

Pedro
 

As you requested,


Thank you.

2017-11-29 10:02 GMT-02:00 Pedro Paulo Canto Martucci <pedrom@...>:

Hi Ravi,

I will send a WIP PR, with my setup and README which allows you to reproduce.

Thanks!

2017-11-29 9:40 GMT-02:00 Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>:
Hi Pedro,

On 11/28/2017 10:12 PM, Pedro Paulo Canto Martucci wrote:
Hi,

I'm trying to validate some RPL features using QEMU. I know it's not the best approach but here we go.
   Yep, we can not completely validate RPL using QEMU. But at-least you started to check some features,
  thanks for that.


For this tests, I'm using 83cf82b7a tag from zephyr git project.

I created a root node to build the RPL network using the code bellow:

'''
#define CURRENT_VERSION 0

void main(void) {
u8_t init_version = CURRENT_VERSION;

char prefix_str[NET_IPV6_ADDR_LEN + 1];
struct in6_addr prefix;
u8_t prefix_len;

printk("RPL root node starting\n");

struct net_if *iface = net_if_get_default();
if (!iface) {
printk("Interface is NULL\n");
printk("Failed to setup RPL root node\n");
return;
}

// Read prefix from KConfig and parse it
memset(prefix_str, 0, sizeof(prefix_str));
memcpy(prefix_str, CONFIG_NET_RPL_PREFIX, min(strlen(CONFIG_NET_RPL_PREFIX), NET_IPV6_ADDR_LEN));

char *slash = strstr(prefix_str, "/");
if (!slash) {
prefix_len = 64;
} else {
*slash = '\0';
prefix_len = atoi(slash + 1);
}

if (prefix_len == 0) {
printk("Invalid prefix length %s", slash + 1);
return;
}

if (net_addr_pton(AF_INET6, prefix_str, &prefix) < 0) {
printk("Invalid IPv6 prefix %s", prefix_str);
return;
}

// Check the current version
if (CURRENT_VERSION == 0) {
// case 0 - call init
init_version = net_rpl_lollipop_init();
} else if (CURRENT_VERSION > 0) {
// case > 0 - increment
net_rpl_lollipop_increment(&init_version);
} else {
printk("CURRENT_VERSION should be greater or eqaul to 0");
return;
}

// Setup the root node
struct net_rpl_dag *dag = net_rpl_set_root_with_version(iface, CONFIG_NET_RPL_DEFAULT_INSTANCE, &prefix, init_version);

if (!dag) {
printk("Cannot set root node");
return;
}

bool ret = net_rpl_set_prefix(iface, dag, &prefix, prefix_len);
if (!ret) {
printk("Cannot set prefix %s/%d", prefix_str, prefix_len);
return;
}
}
'''

Most part of the code are based in pull request #980 and #5035, except version update handling, which I do manually.
   Those PR's are work in progress. It's taking some time test with different topologies and scenarios. Net subsystem
    needs to support some kind flash memory, so I haven't verified 'global repair' scenario.

The leaf node will run an empty main, I'll do the validation just pinging between the nodes using net shell.

On KConfig definitions for root node I setup RPL, 6LoWPAN and uart_pipe driver for 802.15.4:
'''
CONFIG_NET_RPL=y
CONFIG_NET_DEBUG_RPL=y
CONFIG_NET_RPL_GROUNDED=y
CONFIG_NET_RPL_MAX_DAG_PER_INSTANCE=1
CONFIG_NET_RPL_PREFIX="2001:db8::1/64"

# IPv6 (L3)
CONFIG_NET_IPV6=y

# 6LoWPAN (L2 - Adaptation Layer)
CONFIG_NET_6LO=y

# 802.15.4 (L2)
CONFIG_NET_L2_IEEE802154=y
CONFIG_NET_L2_IEEE802154_FRAGMENT=y

# 802.15.4 (L1)
CONFIG_IEEE802154_UPIPE=y

# Enabled Shell Extensions
CONFIG_NET_SHELL=y
CONFIG_NET_L2_IEEE802154_SHELL=y

# Disable default Ethernet interface
CONFIG_NET_SLIP_TAP=n

# Application Settings
CONFIG_NET_APP_SETTINGS=y
CONFIG_NET_APP_MY_IPV6_ADDR="2001:db8::1"
'''

In leaf node:
'''
CONFIG_NET_RPL=y
CONFIG_NET_DEBUG_RPL=y
CONFIG_NET_RPL_MAX_DAG_PER_INSTANCE=1

# IPv6 (L3)
CONFIG_NET_IPV6=y

# 6LoWPAN (L2 - Adaptation Layer)
CONFIG_NET_6LO=y

# 802.15.4 (L2)
CONFIG_NET_L2_IEEE802154=y
CONFIG_NET_L2_IEEE802154_FRAGMENT=y

# 802.15.4 (L1)
CONFIG_IEEE802154_UPIPE=y

# Enabled Shell Extensions
CONFIG_NET_SHELL=y
CONFIG_NET_L2_IEEE802154_SHELL=y

# Disable default Ethernet interface
CONFIG_NET_SLIP_TAP=n
'''

This way, I was able to run the example fine. The root published the prefix in DIO messages, the leaf node joined the DAG with DAO and I managed to ping between hosts using net shell.

My problems started when I tried to simulate a global repair scenario, rebooting the root node. To achieve this, it was necessary to modify some environments configurations.

To setup the QEMU environment I created the pipes manually and disabled removing/creation commands from zephyr/cmake/qemu/CMakeLists.txt in QEMU_NET_STACK session. This way when the 'server' node is rebooted the connection is not lost in the 'client' caused by the pipes recreation.
 
     It would be good to send a WIP PR with your setup and some readme file also. So that I can reproduce the issue and investigate purpose.
 
Also needed to modify get_mac() function from ieee802154_uart_pipe driver to assure that the MAC address assigned to the root node will be always the same:
'''
static inline u8_t *get_mac(struct device *dev)
{
struct upipe_context *upipe = dev->driver_data;


upipe->mac_addr[0] = 0x00;
upipe->mac_addr[1] = 0x10;
upipe->mac_addr[2] = 0x20;
upipe->mac_addr[3] = 0x30;

#if defined(CONFIG_NET_RPL_GROUNDED)
upipe->mac_addr[4] = 0xAA;
upipe->mac_addr[5] = 0xAA;
upipe->mac_addr[6] = 0xAA;
upipe->mac_addr[7] = 0xAA;
#else
UNALIGNED_PUT(sys_cpu_to_be32(sys_rand32_get()),
      (u32_t *) ((void *)upipe->mac_addr+4));
#endif

return upipe->mac_addr;
}
'''

Can you try with these Kconfig options.
 CONFIG_IEEE802154_CC2520_RANDOM_MAC=n
CONFIG_IEEE802154_CC2520_MAC4=0x00
CONFIG_IEEE802154_CC2520_MAC5=0x10
CONFIG_IEEE802154_CC2520_MAC6=0x20
CONFIG_IEEE802154_CC2520_MAC7=0x30


Now I run both applications and wait the network to be configured. After that, I kill the root node, update the constant CURRENT_VERSION in main.c to 240, recompile and rerun it.

The leaf node receives the DIO messages from the root with the new version and and trigger the global repair. During this process it removes the old neighbors/parents and try to setup the new one.

'''
[net/rpl] [DBG] handle_dio: (0x20000558): Received DODAG Information Object from fe80::210:2030:aaaa:aaaa to ff02::1a
[net/rpl] [DBG] handle_dio: (0x20000558): Incoming DIO len 72 id 30 ver 241 rank 256
[net/rpl] [DBG] handle_dio: (0x20000558): Incoming DIO dag_id 2001:db8::1 pref 0
[net/rpl] [DBG] handle_dio: (0x20000558): DIO option 4 length 14
[net/rpl] [DBG] handle_dio: (0x20000558): DAG conf dbl 8 min 12 red 10 maxinc 1792 mininc 256 ocp 1 d_l 255 l_u 65535
[net/rpl] [DBG] handle_dio: (0x20000558): DIO option 8 length 30
[net/rpl] [DBG] handle_dio: (0x20000558): Prefix 2001:db8::/64
[net/rpl] [DBG] net_rpl_process_dio: (0x20000558): Global repair
[net/rpl] [DBG] net_rpl_process_dio: (0x20000558): Prefix announced in DIO
[net/rpl] [DBG] net_rpl_set_prefix: (0x20000558): Prefix is non-NULL, will announce this in DIOs
[net/rpl] [DBG] check_prefix: (0x20000558): Same prefix 2001:db8::/64 flags 0x40
[net/rpl] [DBG] remove_parents: (0x20000558): Removing parents minimum rank 0
[net/rpl] [DBG] net_rpl_remove_parent: (0x20000558): Removing parent fe80::210:2030:aaaa:aaaa [00:10:20:30:AA:AA:AA:AA]
[net/rpl] [DBG] net_rpl_nullify_parent: (0x20000558): Removing default route fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_dao_send: (0x20000558): Send DAO with prefix 2001:db8::210:2030:9b:9856 from fe80::210:2030:9b:9856 to fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): Preferred parent not set
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): It used to be fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_nullify_parent: (0x20000558): Nullifying parent fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] nbr_free: (0x20000558): nbr 0x200062b0
[net/rpl] [DBG] net_rpl_neighbor_data_remove: (0x20000558): Neighbor 0x200062b0 removed
[net/rpl] [DBG] net_rpl_mrhof_reset: (0x20000558): Reset MRHOF
[net/rpl] [DBG] net_rpl_add_parent: (0x20000558): Add parent fe80::210:2030:aaaa:aaaa [00:10:20:30:AA:AA:AA:AA]
[net/rpl] [DBG] nbr_add: (0x20000558): nbr linking failure (-69)
[net/rpl] [DBG] nbr_free: (0x20000558): nbr 0x200062b0
[net/rpl] [DBG] net_rpl_neighbor_data_remove: (0x20000558): Neighbor 0x200062b0 removed
[net/rpl] [DBG] net_rpl_add_parent: (0x20000558): Cannot add RPL neighbor
[net/rpl] [DBG] global_repair: (0x20000558): Failed to add a parent during the global repair
[net/rpl] [DBG] global_repair: (0x20000558): Participating in a global repair version 241 rank 65535
'''

I think it should send a DAO message to the root to rejoin the network if everything is ok, but as we can see in the log it doesn't went right.

I tried to discover the reason why it was unable to add the parent, starting from nbr_add(). I reached to net_nbr_link() function from nbr.c and clearly it failed because of idx check (-EALREADY = -69):
'''
if (nbr->idx != NET_NBR_LLADDR_UNKNOWN) {
return -EALREADY;
}
'''

I don't understand properly the neighbor structures and organization from zephyr to reach any conclusion here, but seems the neighbor passed as argument to net_nbr_link() is not properly cleared as the function expects.

After expending some time on gdb, I verified that the neighbor passed as an argument is the same which was removed right before global repair process. This brings me to net_rpl_neighbor_data_remove() function from rpl.c, which just prints a message and doesn't clear nbr.

Based on this I did a stupid test adding a line to net_rpl_neighbor_data_remove(), just to check what would happen: 
'''
nbr->idx = 0xff;
'''

After rerunning the case I got the RPL network restablished.

'''
[net/rpl] [DBG] handle_dio: (0x20000558): Received DODAG Information Object from fe80::210:2030:aaaa:aaaa to ff02::1a
[net/rpl] [DBG] handle_dio: (0x20000558): Incoming DIO len 72 id 30 ver 241 rank 256
[net/rpl] [DBG] handle_dio: (0x20000558): Incoming DIO dag_id 2001:db8::1 pref 0
[net/rpl] [DBG] handle_dio: (0x20000558): DIO option 4 length 14
[net/rpl] [DBG] handle_dio: (0x20000558): DAG conf dbl 8 min 12 red 10 maxinc 1792 mininc 256 ocp 1 d_l 255 l_u 65535
[net/rpl] [DBG] handle_dio: (0x20000558): DIO option 8 length 30
[net/rpl] [DBG] handle_dio: (0x20000558): Prefix 2001:db8::/64
[net/rpl] [DBG] net_rpl_process_dio: (0x20000558): Global repair
[net/rpl] [DBG] net_rpl_process_dio: (0x20000558): Prefix announced in DIO
[net/rpl] [DBG] net_rpl_set_prefix: (0x20000558): Prefix is non-NULL, will announce this in DIOs
[net/rpl] [DBG] check_prefix: (0x20000558): Same prefix 2001:db8::/64 flags 0x40
[net/rpl] [DBG] remove_parents: (0x20000558): Removing parents minimum rank 0
[net/rpl] [DBG] net_rpl_remove_parent: (0x20000558): Removing parent fe80::210:2030:aaaa:aaaa [00:10:20:30:AA:AA:AA:AA]
[net/rpl] [DBG] net_rpl_nullify_parent: (0x20000558): Removing default route fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_dao_send: (0x20000558): Send DAO with prefix 2001:db8::210:2030:9c:475a from fe80::210:2030:9c:475a to fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): Preferred parent not set
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): It used to be fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_nullify_parent: (0x20000558): Nullifying parent fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] nbr_free: (0x20000558): nbr 0x200062b0
[net/rpl] [DBG] net_rpl_neighbor_data_remove: (0x20000558): Neighbor 0x200062b0 removed
[net/rpl] [DBG] net_rpl_mrhof_reset: (0x20000558): Reset MRHOF
[net/rpl] [DBG] net_rpl_add_parent: (0x20000558): Add parent fe80::210:2030:aaaa:aaaa [00:10:20:30:AA:AA:AA:AA]
[net/rpl] [DBG] nbr_add: (0x20000558): [0] nbr 0x200062b0 IPv6 fe80::210:2030:aaaa:aaaa ll 00:10:20:30:AA:AA:AA:AA iface 0x200067a0
[net/rpl] [DBG] net_rpl_add_parent: (0x20000558): [0] nbr 0x200062b0 parent 0x200062c4
[net/rpl] [DBG] global_repair: (0x20000558): Starting global repair
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): Preferred parent fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): It used to be not set
[net/rpl] [DBG] net_rpl_set_default_route: (0x20000558): Adding default route through fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_select_dag: (0x20000558): Changed preferred parent, rank changed from 768 to 768
[net/rpl] [DBG] schedule_dao: (0x20000558): Scheduling DAO timer 4800 ms in the future
[net/rpl] [DBG] dao_timer: (0x20000cb0): Sending DAO iface 0x200067a0
[net/rpl] [DBG] net_rpl_dao_send: (0x20000cb0): Send DAO with prefix 2001:db8::210:2030:9c:475a from fe80::210:2030:9c:475a to fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_link_neighbor_callback: (0x2000060c): Neighbor link callback triggering update
[net/rpl] [DBG] handle_dao_ack: (0x20000558): Received Destination Advertisement Object Ack from fe80::210:2030:aaaa:aaaa to fe80::210:2030:9c:475a
[net/rpl] [DBG] handle_dao_ack: (0x20000558): Received a DAO ACK with seq number 244(244) status 0 from fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] handle_dao_ack: (0x20000558): Status ACK
'''

Clearly my approach wasn't correct, I don't even understand properly the neighbor dynamics. Did I miss something in my setup which might have caused this behavior? Or there are something wrong on neighbor management?

At-least now I will investigate with above logs, it would be good if you can send your patches and steps to reproduce.

Thanks,
Ravi.
Thank you!

--
Att,
Pedro Martucci
---
Gerência de Tecnologias de Controle e Inteligência de Sistemas
CPqD - Diretoria de Tecnologias de Comunicação
Tel.: +55 19 3705-5995


_______________________________________________
Zephyr-devel mailing list
Zephyr-devel@...ct.org
https://lists.zephyrproject.org/mailman/listinfo/zephyr-devel




--
Att,
Pedro Martucci
---
Gerência de Tecnologias de Controle e Inteligência de Sistemas
CPqD - Diretoria de Tecnologias de Comunicação
Tel.: +55 19 3705-5995



--
Att,
Pedro Martucci
---
Gerência de Tecnologias de Controle e Inteligência de Sistemas
CPqD - Diretoria de Tecnologias de Comunicação
Tel.: +55 19 3705-5995


Re: Determining type of device

Felipe Neves
 

Hi Johannes, as far I know, the device structure is formed by generic pointers in all its fields, in a first look this stills a good approach to keep the flexibility and while keeps the device API uniform, on other hand it is not a type-safe, so you cannot determine which type of device using only the device structure.

Please let me know if this info was useful.

Felipe

2017-11-29 13:51 GMT-02:00 Johannes Hutter <johannes@...>:

Hello everyone,


is there a zephyr-way in determining which type a device is, after getting a reference to it through device_get_binding?

Since a gpio device has the same signature as a flash for example it's not obvious for me how to make sure that the right device pointer is passed in a higer-level application.


Thanks in advance,

Joe

--
Johannes Hutter ¦ Embedded Software Developer
Mail: johannes@...


Workaround GmbH (ProGlove)
Friedenstr. 4 | 81671 München

Managing Director: Thomas Kirchner
HRB: 216605 | AG München
USt.-IdNr.: DE298859320

_______________________________________________
Zephyr-users mailing list
Zephyr-users@...ct.org
https://lists.zephyrproject.org/mailman/listinfo/zephyr-users



--
Felipe S. Neves 
Embedded software & systems engineer
Skype: fneves1989
+55 11 96610 – 0855 


Determining type of device

Johannes Hutter
 

Hello everyone,


is there a zephyr-way in determining which type a device is, after getting a reference to it through device_get_binding?

Since a gpio device has the same signature as a flash for example it's not obvious for me how to make sure that the right device pointer is passed in a higer-level application.


Thanks in advance,

Joe

--
Johannes Hutter ¦ Embedded Software Developer
Mail: johannes@proglove.de


Workaround GmbH (ProGlove)
Friedenstr. 4 | 81671 München

Managing Director: Thomas Kirchner
HRB: 216605 | AG München
USt.-IdNr.: DE298859320


Re: [Zephyr-devel] RPL Tests

Pedro
 

Hi Ravi,

I will send a WIP PR, with my setup and README which allows you to reproduce.

Thanks!

2017-11-29 9:40 GMT-02:00 Ravi kumar Veeramally <ravikumar.veeramally@...>:

Hi Pedro,

On 11/28/2017 10:12 PM, Pedro Paulo Canto Martucci wrote:
Hi,

I'm trying to validate some RPL features using QEMU. I know it's not the best approach but here we go.
   Yep, we can not completely validate RPL using QEMU. But at-least you started to check some features,
  thanks for that.


For this tests, I'm using 83cf82b7a tag from zephyr git project.

I created a root node to build the RPL network using the code bellow:

'''
#define CURRENT_VERSION 0

void main(void) {
u8_t init_version = CURRENT_VERSION;

char prefix_str[NET_IPV6_ADDR_LEN + 1];
struct in6_addr prefix;
u8_t prefix_len;

printk("RPL root node starting\n");

struct net_if *iface = net_if_get_default();
if (!iface) {
printk("Interface is NULL\n");
printk("Failed to setup RPL root node\n");
return;
}

// Read prefix from KConfig and parse it
memset(prefix_str, 0, sizeof(prefix_str));
memcpy(prefix_str, CONFIG_NET_RPL_PREFIX, min(strlen(CONFIG_NET_RPL_PREFIX), NET_IPV6_ADDR_LEN));

char *slash = strstr(prefix_str, "/");
if (!slash) {
prefix_len = 64;
} else {
*slash = '\0';
prefix_len = atoi(slash + 1);
}

if (prefix_len == 0) {
printk("Invalid prefix length %s", slash + 1);
return;
}

if (net_addr_pton(AF_INET6, prefix_str, &prefix) < 0) {
printk("Invalid IPv6 prefix %s", prefix_str);
return;
}

// Check the current version
if (CURRENT_VERSION == 0) {
// case 0 - call init
init_version = net_rpl_lollipop_init();
} else if (CURRENT_VERSION > 0) {
// case > 0 - increment
net_rpl_lollipop_increment(&init_version);
} else {
printk("CURRENT_VERSION should be greater or eqaul to 0");
return;
}

// Setup the root node
struct net_rpl_dag *dag = net_rpl_set_root_with_version(iface, CONFIG_NET_RPL_DEFAULT_INSTANCE, &prefix, init_version);

if (!dag) {
printk("Cannot set root node");
return;
}

bool ret = net_rpl_set_prefix(iface, dag, &prefix, prefix_len);
if (!ret) {
printk("Cannot set prefix %s/%d", prefix_str, prefix_len);
return;
}
}
'''

Most part of the code are based in pull request #980 and #5035, except version update handling, which I do manually.
   Those PR's are work in progress. It's taking some time test with different topologies and scenarios. Net subsystem
    needs to support some kind flash memory, so I haven't verified 'global repair' scenario.

The leaf node will run an empty main, I'll do the validation just pinging between the nodes using net shell.

On KConfig definitions for root node I setup RPL, 6LoWPAN and uart_pipe driver for 802.15.4:
'''
CONFIG_NET_RPL=y
CONFIG_NET_DEBUG_RPL=y
CONFIG_NET_RPL_GROUNDED=y
CONFIG_NET_RPL_MAX_DAG_PER_INSTANCE=1
CONFIG_NET_RPL_PREFIX="2001:db8::1/64"

# IPv6 (L3)
CONFIG_NET_IPV6=y

# 6LoWPAN (L2 - Adaptation Layer)
CONFIG_NET_6LO=y

# 802.15.4 (L2)
CONFIG_NET_L2_IEEE802154=y
CONFIG_NET_L2_IEEE802154_FRAGMENT=y

# 802.15.4 (L1)
CONFIG_IEEE802154_UPIPE=y

# Enabled Shell Extensions
CONFIG_NET_SHELL=y
CONFIG_NET_L2_IEEE802154_SHELL=y

# Disable default Ethernet interface
CONFIG_NET_SLIP_TAP=n

# Application Settings
CONFIG_NET_APP_SETTINGS=y
CONFIG_NET_APP_MY_IPV6_ADDR="2001:db8::1"
'''

In leaf node:
'''
CONFIG_NET_RPL=y
CONFIG_NET_DEBUG_RPL=y
CONFIG_NET_RPL_MAX_DAG_PER_INSTANCE=1

# IPv6 (L3)
CONFIG_NET_IPV6=y

# 6LoWPAN (L2 - Adaptation Layer)
CONFIG_NET_6LO=y

# 802.15.4 (L2)
CONFIG_NET_L2_IEEE802154=y
CONFIG_NET_L2_IEEE802154_FRAGMENT=y

# 802.15.4 (L1)
CONFIG_IEEE802154_UPIPE=y

# Enabled Shell Extensions
CONFIG_NET_SHELL=y
CONFIG_NET_L2_IEEE802154_SHELL=y

# Disable default Ethernet interface
CONFIG_NET_SLIP_TAP=n
'''

This way, I was able to run the example fine. The root published the prefix in DIO messages, the leaf node joined the DAG with DAO and I managed to ping between hosts using net shell.

My problems started when I tried to simulate a global repair scenario, rebooting the root node. To achieve this, it was necessary to modify some environments configurations.

To setup the QEMU environment I created the pipes manually and disabled removing/creation commands from zephyr/cmake/qemu/CMakeLists.txt in QEMU_NET_STACK session. This way when the 'server' node is rebooted the connection is not lost in the 'client' caused by the pipes recreation.
 
     It would be good to send a WIP PR with your setup and some readme file also. So that I can reproduce the issue and investigate purpose.
 
Also needed to modify get_mac() function from ieee802154_uart_pipe driver to assure that the MAC address assigned to the root node will be always the same:
'''
static inline u8_t *get_mac(struct device *dev)
{
struct upipe_context *upipe = dev->driver_data;


upipe->mac_addr[0] = 0x00;
upipe->mac_addr[1] = 0x10;
upipe->mac_addr[2] = 0x20;
upipe->mac_addr[3] = 0x30;

#if defined(CONFIG_NET_RPL_GROUNDED)
upipe->mac_addr[4] = 0xAA;
upipe->mac_addr[5] = 0xAA;
upipe->mac_addr[6] = 0xAA;
upipe->mac_addr[7] = 0xAA;
#else
UNALIGNED_PUT(sys_cpu_to_be32(sys_rand32_get()),
      (u32_t *) ((void *)upipe->mac_addr+4));
#endif

return upipe->mac_addr;
}
'''

Can you try with these Kconfig options.
 CONFIG_IEEE802154_CC2520_RANDOM_MAC=n
CONFIG_IEEE802154_CC2520_MAC4=0x00
CONFIG_IEEE802154_CC2520_MAC5=0x10
CONFIG_IEEE802154_CC2520_MAC6=0x20
CONFIG_IEEE802154_CC2520_MAC7=0x30


Now I run both applications and wait the network to be configured. After that, I kill the root node, update the constant CURRENT_VERSION in main.c to 240, recompile and rerun it.

The leaf node receives the DIO messages from the root with the new version and and trigger the global repair. During this process it removes the old neighbors/parents and try to setup the new one.

'''
[net/rpl] [DBG] handle_dio: (0x20000558): Received DODAG Information Object from fe80::210:2030:aaaa:aaaa to ff02::1a
[net/rpl] [DBG] handle_dio: (0x20000558): Incoming DIO len 72 id 30 ver 241 rank 256
[net/rpl] [DBG] handle_dio: (0x20000558): Incoming DIO dag_id 2001:db8::1 pref 0
[net/rpl] [DBG] handle_dio: (0x20000558): DIO option 4 length 14
[net/rpl] [DBG] handle_dio: (0x20000558): DAG conf dbl 8 min 12 red 10 maxinc 1792 mininc 256 ocp 1 d_l 255 l_u 65535
[net/rpl] [DBG] handle_dio: (0x20000558): DIO option 8 length 30
[net/rpl] [DBG] handle_dio: (0x20000558): Prefix 2001:db8::/64
[net/rpl] [DBG] net_rpl_process_dio: (0x20000558): Global repair
[net/rpl] [DBG] net_rpl_process_dio: (0x20000558): Prefix announced in DIO
[net/rpl] [DBG] net_rpl_set_prefix: (0x20000558): Prefix is non-NULL, will announce this in DIOs
[net/rpl] [DBG] check_prefix: (0x20000558): Same prefix 2001:db8::/64 flags 0x40
[net/rpl] [DBG] remove_parents: (0x20000558): Removing parents minimum rank 0
[net/rpl] [DBG] net_rpl_remove_parent: (0x20000558): Removing parent fe80::210:2030:aaaa:aaaa [00:10:20:30:AA:AA:AA:AA]
[net/rpl] [DBG] net_rpl_nullify_parent: (0x20000558): Removing default route fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_dao_send: (0x20000558): Send DAO with prefix 2001:db8::210:2030:9b:9856 from fe80::210:2030:9b:9856 to fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): Preferred parent not set
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): It used to be fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_nullify_parent: (0x20000558): Nullifying parent fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] nbr_free: (0x20000558): nbr 0x200062b0
[net/rpl] [DBG] net_rpl_neighbor_data_remove: (0x20000558): Neighbor 0x200062b0 removed
[net/rpl] [DBG] net_rpl_mrhof_reset: (0x20000558): Reset MRHOF
[net/rpl] [DBG] net_rpl_add_parent: (0x20000558): Add parent fe80::210:2030:aaaa:aaaa [00:10:20:30:AA:AA:AA:AA]
[net/rpl] [DBG] nbr_add: (0x20000558): nbr linking failure (-69)
[net/rpl] [DBG] nbr_free: (0x20000558): nbr 0x200062b0
[net/rpl] [DBG] net_rpl_neighbor_data_remove: (0x20000558): Neighbor 0x200062b0 removed
[net/rpl] [DBG] net_rpl_add_parent: (0x20000558): Cannot add RPL neighbor
[net/rpl] [DBG] global_repair: (0x20000558): Failed to add a parent during the global repair
[net/rpl] [DBG] global_repair: (0x20000558): Participating in a global repair version 241 rank 65535
'''

I think it should send a DAO message to the root to rejoin the network if everything is ok, but as we can see in the log it doesn't went right.

I tried to discover the reason why it was unable to add the parent, starting from nbr_add(). I reached to net_nbr_link() function from nbr.c and clearly it failed because of idx check (-EALREADY = -69):
'''
if (nbr->idx != NET_NBR_LLADDR_UNKNOWN) {
return -EALREADY;
}
'''

I don't understand properly the neighbor structures and organization from zephyr to reach any conclusion here, but seems the neighbor passed as argument to net_nbr_link() is not properly cleared as the function expects.

After expending some time on gdb, I verified that the neighbor passed as an argument is the same which was removed right before global repair process. This brings me to net_rpl_neighbor_data_remove() function from rpl.c, which just prints a message and doesn't clear nbr.

Based on this I did a stupid test adding a line to net_rpl_neighbor_data_remove(), just to check what would happen: 
'''
nbr->idx = 0xff;
'''

After rerunning the case I got the RPL network restablished.

'''
[net/rpl] [DBG] handle_dio: (0x20000558): Received DODAG Information Object from fe80::210:2030:aaaa:aaaa to ff02::1a
[net/rpl] [DBG] handle_dio: (0x20000558): Incoming DIO len 72 id 30 ver 241 rank 256
[net/rpl] [DBG] handle_dio: (0x20000558): Incoming DIO dag_id 2001:db8::1 pref 0
[net/rpl] [DBG] handle_dio: (0x20000558): DIO option 4 length 14
[net/rpl] [DBG] handle_dio: (0x20000558): DAG conf dbl 8 min 12 red 10 maxinc 1792 mininc 256 ocp 1 d_l 255 l_u 65535
[net/rpl] [DBG] handle_dio: (0x20000558): DIO option 8 length 30
[net/rpl] [DBG] handle_dio: (0x20000558): Prefix 2001:db8::/64
[net/rpl] [DBG] net_rpl_process_dio: (0x20000558): Global repair
[net/rpl] [DBG] net_rpl_process_dio: (0x20000558): Prefix announced in DIO
[net/rpl] [DBG] net_rpl_set_prefix: (0x20000558): Prefix is non-NULL, will announce this in DIOs
[net/rpl] [DBG] check_prefix: (0x20000558): Same prefix 2001:db8::/64 flags 0x40
[net/rpl] [DBG] remove_parents: (0x20000558): Removing parents minimum rank 0
[net/rpl] [DBG] net_rpl_remove_parent: (0x20000558): Removing parent fe80::210:2030:aaaa:aaaa [00:10:20:30:AA:AA:AA:AA]
[net/rpl] [DBG] net_rpl_nullify_parent: (0x20000558): Removing default route fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_dao_send: (0x20000558): Send DAO with prefix 2001:db8::210:2030:9c:475a from fe80::210:2030:9c:475a to fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): Preferred parent not set
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): It used to be fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_nullify_parent: (0x20000558): Nullifying parent fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] nbr_free: (0x20000558): nbr 0x200062b0
[net/rpl] [DBG] net_rpl_neighbor_data_remove: (0x20000558): Neighbor 0x200062b0 removed
[net/rpl] [DBG] net_rpl_mrhof_reset: (0x20000558): Reset MRHOF
[net/rpl] [DBG] net_rpl_add_parent: (0x20000558): Add parent fe80::210:2030:aaaa:aaaa [00:10:20:30:AA:AA:AA:AA]
[net/rpl] [DBG] nbr_add: (0x20000558): [0] nbr 0x200062b0 IPv6 fe80::210:2030:aaaa:aaaa ll 00:10:20:30:AA:AA:AA:AA iface 0x200067a0
[net/rpl] [DBG] net_rpl_add_parent: (0x20000558): [0] nbr 0x200062b0 parent 0x200062c4
[net/rpl] [DBG] global_repair: (0x20000558): Starting global repair
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): Preferred parent fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): It used to be not set
[net/rpl] [DBG] net_rpl_set_default_route: (0x20000558): Adding default route through fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_select_dag: (0x20000558): Changed preferred parent, rank changed from 768 to 768
[net/rpl] [DBG] schedule_dao: (0x20000558): Scheduling DAO timer 4800 ms in the future
[net/rpl] [DBG] dao_timer: (0x20000cb0): Sending DAO iface 0x200067a0
[net/rpl] [DBG] net_rpl_dao_send: (0x20000cb0): Send DAO with prefix 2001:db8::210:2030:9c:475a from fe80::210:2030:9c:475a to fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_link_neighbor_callback: (0x2000060c): Neighbor link callback triggering update
[net/rpl] [DBG] handle_dao_ack: (0x20000558): Received Destination Advertisement Object Ack from fe80::210:2030:aaaa:aaaa to fe80::210:2030:9c:475a
[net/rpl] [DBG] handle_dao_ack: (0x20000558): Received a DAO ACK with seq number 244(244) status 0 from fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] handle_dao_ack: (0x20000558): Status ACK
'''

Clearly my approach wasn't correct, I don't even understand properly the neighbor dynamics. Did I miss something in my setup which might have caused this behavior? Or there are something wrong on neighbor management?

At-least now I will investigate with above logs, it would be good if you can send your patches and steps to reproduce.

Thanks,
Ravi.
Thank you!

--
Att,
Pedro Martucci
---
Gerência de Tecnologias de Controle e Inteligência de Sistemas
CPqD - Diretoria de Tecnologias de Comunicação
Tel.: +55 19 3705-5995


_______________________________________________
Zephyr-devel mailing list
Zephyr-devel@lists.zephyrproject.org
https://lists.zephyrproject.org/mailman/listinfo/zephyr-devel




--
Att,
Pedro Martucci
---
Gerência de Tecnologias de Controle e Inteligência de Sistemas
CPqD - Diretoria de Tecnologias de Comunicação
Tel.: +55 19 3705-5995


Re: [Zephyr-devel] RPL Tests

Ravi kumar Veeramally <ravikumar.veeramally@...>
 

Hi Pedro,

On 11/28/2017 10:12 PM, Pedro Paulo Canto Martucci wrote:
Hi,

I'm trying to validate some RPL features using QEMU. I know it's not the best approach but here we go.
   Yep, we can not completely validate RPL using QEMU. But at-least you started to check some features,
  thanks for that.

For this tests, I'm using 83cf82b7a tag from zephyr git project.

I created a root node to build the RPL network using the code bellow:

'''
#define CURRENT_VERSION 0

void main(void) {
u8_t init_version = CURRENT_VERSION;

char prefix_str[NET_IPV6_ADDR_LEN + 1];
struct in6_addr prefix;
u8_t prefix_len;

printk("RPL root node starting\n");

struct net_if *iface = net_if_get_default();
if (!iface) {
printk("Interface is NULL\n");
printk("Failed to setup RPL root node\n");
return;
}

// Read prefix from KConfig and parse it
memset(prefix_str, 0, sizeof(prefix_str));
memcpy(prefix_str, CONFIG_NET_RPL_PREFIX, min(strlen(CONFIG_NET_RPL_PREFIX), NET_IPV6_ADDR_LEN));

char *slash = strstr(prefix_str, "/");
if (!slash) {
prefix_len = 64;
} else {
*slash = '\0';
prefix_len = atoi(slash + 1);
}

if (prefix_len == 0) {
printk("Invalid prefix length %s", slash + 1);
return;
}

if (net_addr_pton(AF_INET6, prefix_str, &prefix) < 0) {
printk("Invalid IPv6 prefix %s", prefix_str);
return;
}

// Check the current version
if (CURRENT_VERSION == 0) {
// case 0 - call init
init_version = net_rpl_lollipop_init();
} else if (CURRENT_VERSION > 0) {
// case > 0 - increment
net_rpl_lollipop_increment(&init_version);
} else {
printk("CURRENT_VERSION should be greater or eqaul to 0");
return;
}

// Setup the root node
struct net_rpl_dag *dag = net_rpl_set_root_with_version(iface, CONFIG_NET_RPL_DEFAULT_INSTANCE, &prefix, init_version);

if (!dag) {
printk("Cannot set root node");
return;
}

bool ret = net_rpl_set_prefix(iface, dag, &prefix, prefix_len);
if (!ret) {
printk("Cannot set prefix %s/%d", prefix_str, prefix_len);
return;
}
}
'''

Most part of the code are based in pull request #980 and #5035, except version update handling, which I do manually.
   Those PR's are work in progress. It's taking some time test with different topologies and scenarios. Net subsystem
    needs to support some kind flash memory, so I haven't verified 'global repair' scenario.

The leaf node will run an empty main, I'll do the validation just pinging between the nodes using net shell.

On KConfig definitions for root node I setup RPL, 6LoWPAN and uart_pipe driver for 802.15.4:
'''
CONFIG_NET_RPL=y
CONFIG_NET_DEBUG_RPL=y
CONFIG_NET_RPL_GROUNDED=y
CONFIG_NET_RPL_MAX_DAG_PER_INSTANCE=1
CONFIG_NET_RPL_PREFIX="2001:db8::1/64"

# IPv6 (L3)
CONFIG_NET_IPV6=y

# 6LoWPAN (L2 - Adaptation Layer)
CONFIG_NET_6LO=y

# 802.15.4 (L2)
CONFIG_NET_L2_IEEE802154=y
CONFIG_NET_L2_IEEE802154_FRAGMENT=y

# 802.15.4 (L1)
CONFIG_IEEE802154_UPIPE=y

# Enabled Shell Extensions
CONFIG_NET_SHELL=y
CONFIG_NET_L2_IEEE802154_SHELL=y

# Disable default Ethernet interface
CONFIG_NET_SLIP_TAP=n

# Application Settings
CONFIG_NET_APP_SETTINGS=y
CONFIG_NET_APP_MY_IPV6_ADDR="2001:db8::1"
'''

In leaf node:
'''
CONFIG_NET_RPL=y
CONFIG_NET_DEBUG_RPL=y
CONFIG_NET_RPL_MAX_DAG_PER_INSTANCE=1

# IPv6 (L3)
CONFIG_NET_IPV6=y

# 6LoWPAN (L2 - Adaptation Layer)
CONFIG_NET_6LO=y

# 802.15.4 (L2)
CONFIG_NET_L2_IEEE802154=y
CONFIG_NET_L2_IEEE802154_FRAGMENT=y

# 802.15.4 (L1)
CONFIG_IEEE802154_UPIPE=y

# Enabled Shell Extensions
CONFIG_NET_SHELL=y
CONFIG_NET_L2_IEEE802154_SHELL=y

# Disable default Ethernet interface
CONFIG_NET_SLIP_TAP=n
'''

This way, I was able to run the example fine. The root published the prefix in DIO messages, the leaf node joined the DAG with DAO and I managed to ping between hosts using net shell.

My problems started when I tried to simulate a global repair scenario, rebooting the root node. To achieve this, it was necessary to modify some environments configurations.

To setup the QEMU environment I created the pipes manually and disabled removing/creation commands from zephyr/cmake/qemu/CMakeLists.txt in QEMU_NET_STACK session. This way when the 'server' node is rebooted the connection is not lost in the 'client' caused by the pipes recreation.
 
     It would be good to send a WIP PR with your setup and some readme file also. So that I can reproduce the issue and investigate purpose.
 
Also needed to modify get_mac() function from ieee802154_uart_pipe driver to assure that the MAC address assigned to the root node will be always the same:
'''
static inline u8_t *get_mac(struct device *dev)
{
struct upipe_context *upipe = dev->driver_data;


upipe->mac_addr[0] = 0x00;
upipe->mac_addr[1] = 0x10;
upipe->mac_addr[2] = 0x20;
upipe->mac_addr[3] = 0x30;

#if defined(CONFIG_NET_RPL_GROUNDED)
upipe->mac_addr[4] = 0xAA;
upipe->mac_addr[5] = 0xAA;
upipe->mac_addr[6] = 0xAA;
upipe->mac_addr[7] = 0xAA;
#else
UNALIGNED_PUT(sys_cpu_to_be32(sys_rand32_get()),
      (u32_t *) ((void *)upipe->mac_addr+4));
#endif

return upipe->mac_addr;
}
'''

Can you try with these Kconfig options.
 CONFIG_IEEE802154_CC2520_RANDOM_MAC=n
CONFIG_IEEE802154_CC2520_MAC4=0x00
CONFIG_IEEE802154_CC2520_MAC5=0x10
CONFIG_IEEE802154_CC2520_MAC6=0x20
CONFIG_IEEE802154_CC2520_MAC7=0x30

Now I run both applications and wait the network to be configured. After that, I kill the root node, update the constant CURRENT_VERSION in main.c to 240, recompile and rerun it.

The leaf node receives the DIO messages from the root with the new version and and trigger the global repair. During this process it removes the old neighbors/parents and try to setup the new one.

'''
[net/rpl] [DBG] handle_dio: (0x20000558): Received DODAG Information Object from fe80::210:2030:aaaa:aaaa to ff02::1a
[net/rpl] [DBG] handle_dio: (0x20000558): Incoming DIO len 72 id 30 ver 241 rank 256
[net/rpl] [DBG] handle_dio: (0x20000558): Incoming DIO dag_id 2001:db8::1 pref 0
[net/rpl] [DBG] handle_dio: (0x20000558): DIO option 4 length 14
[net/rpl] [DBG] handle_dio: (0x20000558): DAG conf dbl 8 min 12 red 10 maxinc 1792 mininc 256 ocp 1 d_l 255 l_u 65535
[net/rpl] [DBG] handle_dio: (0x20000558): DIO option 8 length 30
[net/rpl] [DBG] handle_dio: (0x20000558): Prefix 2001:db8::/64
[net/rpl] [DBG] net_rpl_process_dio: (0x20000558): Global repair
[net/rpl] [DBG] net_rpl_process_dio: (0x20000558): Prefix announced in DIO
[net/rpl] [DBG] net_rpl_set_prefix: (0x20000558): Prefix is non-NULL, will announce this in DIOs
[net/rpl] [DBG] check_prefix: (0x20000558): Same prefix 2001:db8::/64 flags 0x40
[net/rpl] [DBG] remove_parents: (0x20000558): Removing parents minimum rank 0
[net/rpl] [DBG] net_rpl_remove_parent: (0x20000558): Removing parent fe80::210:2030:aaaa:aaaa [00:10:20:30:AA:AA:AA:AA]
[net/rpl] [DBG] net_rpl_nullify_parent: (0x20000558): Removing default route fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_dao_send: (0x20000558): Send DAO with prefix 2001:db8::210:2030:9b:9856 from fe80::210:2030:9b:9856 to fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): Preferred parent not set
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): It used to be fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_nullify_parent: (0x20000558): Nullifying parent fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] nbr_free: (0x20000558): nbr 0x200062b0
[net/rpl] [DBG] net_rpl_neighbor_data_remove: (0x20000558): Neighbor 0x200062b0 removed
[net/rpl] [DBG] net_rpl_mrhof_reset: (0x20000558): Reset MRHOF
[net/rpl] [DBG] net_rpl_add_parent: (0x20000558): Add parent fe80::210:2030:aaaa:aaaa [00:10:20:30:AA:AA:AA:AA]
[net/rpl] [DBG] nbr_add: (0x20000558): nbr linking failure (-69)
[net/rpl] [DBG] nbr_free: (0x20000558): nbr 0x200062b0
[net/rpl] [DBG] net_rpl_neighbor_data_remove: (0x20000558): Neighbor 0x200062b0 removed
[net/rpl] [DBG] net_rpl_add_parent: (0x20000558): Cannot add RPL neighbor
[net/rpl] [DBG] global_repair: (0x20000558): Failed to add a parent during the global repair
[net/rpl] [DBG] global_repair: (0x20000558): Participating in a global repair version 241 rank 65535
'''

I think it should send a DAO message to the root to rejoin the network if everything is ok, but as we can see in the log it doesn't went right.

I tried to discover the reason why it was unable to add the parent, starting from nbr_add(). I reached to net_nbr_link() function from nbr.c and clearly it failed because of idx check (-EALREADY = -69):
'''
if (nbr->idx != NET_NBR_LLADDR_UNKNOWN) {
return -EALREADY;
}
'''

I don't understand properly the neighbor structures and organization from zephyr to reach any conclusion here, but seems the neighbor passed as argument to net_nbr_link() is not properly cleared as the function expects.

After expending some time on gdb, I verified that the neighbor passed as an argument is the same which was removed right before global repair process. This brings me to net_rpl_neighbor_data_remove() function from rpl.c, which just prints a message and doesn't clear nbr.

Based on this I did a stupid test adding a line to net_rpl_neighbor_data_remove(), just to check what would happen: 
'''
nbr->idx = 0xff;
'''

After rerunning the case I got the RPL network restablished.

'''
[net/rpl] [DBG] handle_dio: (0x20000558): Received DODAG Information Object from fe80::210:2030:aaaa:aaaa to ff02::1a
[net/rpl] [DBG] handle_dio: (0x20000558): Incoming DIO len 72 id 30 ver 241 rank 256
[net/rpl] [DBG] handle_dio: (0x20000558): Incoming DIO dag_id 2001:db8::1 pref 0
[net/rpl] [DBG] handle_dio: (0x20000558): DIO option 4 length 14
[net/rpl] [DBG] handle_dio: (0x20000558): DAG conf dbl 8 min 12 red 10 maxinc 1792 mininc 256 ocp 1 d_l 255 l_u 65535
[net/rpl] [DBG] handle_dio: (0x20000558): DIO option 8 length 30
[net/rpl] [DBG] handle_dio: (0x20000558): Prefix 2001:db8::/64
[net/rpl] [DBG] net_rpl_process_dio: (0x20000558): Global repair
[net/rpl] [DBG] net_rpl_process_dio: (0x20000558): Prefix announced in DIO
[net/rpl] [DBG] net_rpl_set_prefix: (0x20000558): Prefix is non-NULL, will announce this in DIOs
[net/rpl] [DBG] check_prefix: (0x20000558): Same prefix 2001:db8::/64 flags 0x40
[net/rpl] [DBG] remove_parents: (0x20000558): Removing parents minimum rank 0
[net/rpl] [DBG] net_rpl_remove_parent: (0x20000558): Removing parent fe80::210:2030:aaaa:aaaa [00:10:20:30:AA:AA:AA:AA]
[net/rpl] [DBG] net_rpl_nullify_parent: (0x20000558): Removing default route fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_dao_send: (0x20000558): Send DAO with prefix 2001:db8::210:2030:9c:475a from fe80::210:2030:9c:475a to fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): Preferred parent not set
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): It used to be fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_nullify_parent: (0x20000558): Nullifying parent fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] nbr_free: (0x20000558): nbr 0x200062b0
[net/rpl] [DBG] net_rpl_neighbor_data_remove: (0x20000558): Neighbor 0x200062b0 removed
[net/rpl] [DBG] net_rpl_mrhof_reset: (0x20000558): Reset MRHOF
[net/rpl] [DBG] net_rpl_add_parent: (0x20000558): Add parent fe80::210:2030:aaaa:aaaa [00:10:20:30:AA:AA:AA:AA]
[net/rpl] [DBG] nbr_add: (0x20000558): [0] nbr 0x200062b0 IPv6 fe80::210:2030:aaaa:aaaa ll 00:10:20:30:AA:AA:AA:AA iface 0x200067a0
[net/rpl] [DBG] net_rpl_add_parent: (0x20000558): [0] nbr 0x200062b0 parent 0x200062c4
[net/rpl] [DBG] global_repair: (0x20000558): Starting global repair
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): Preferred parent fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): It used to be not set
[net/rpl] [DBG] net_rpl_set_default_route: (0x20000558): Adding default route through fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_select_dag: (0x20000558): Changed preferred parent, rank changed from 768 to 768
[net/rpl] [DBG] schedule_dao: (0x20000558): Scheduling DAO timer 4800 ms in the future
[net/rpl] [DBG] dao_timer: (0x20000cb0): Sending DAO iface 0x200067a0
[net/rpl] [DBG] net_rpl_dao_send: (0x20000cb0): Send DAO with prefix 2001:db8::210:2030:9c:475a from fe80::210:2030:9c:475a to fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_link_neighbor_callback: (0x2000060c): Neighbor link callback triggering update
[net/rpl] [DBG] handle_dao_ack: (0x20000558): Received Destination Advertisement Object Ack from fe80::210:2030:aaaa:aaaa to fe80::210:2030:9c:475a
[net/rpl] [DBG] handle_dao_ack: (0x20000558): Received a DAO ACK with seq number 244(244) status 0 from fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] handle_dao_ack: (0x20000558): Status ACK
'''

Clearly my approach wasn't correct, I don't even understand properly the neighbor dynamics. Did I miss something in my setup which might have caused this behavior? Or there are something wrong on neighbor management?

At-least now I will investigate with above logs, it would be good if you can send your patches and steps to reproduce.

Thanks,
Ravi.
Thank you!

--
Att,
Pedro Martucci
---
Gerência de Tecnologias de Controle e Inteligência de Sistemas
CPqD - Diretoria de Tecnologias de Comunicação
Tel.: +55 19 3705-5995


_______________________________________________
Zephyr-devel mailing list
Zephyr-devel@...
https://lists.zephyrproject.org/mailman/listinfo/zephyr-devel


RPL Tests

Pedro
 

Hi,

I'm trying to validate some RPL features using QEMU. I know it's not the best approach but here we go.

For this tests, I'm using 83cf82b7a tag from zephyr git project.

I created a root node to build the RPL network using the code bellow:

'''
#define CURRENT_VERSION 0

void main(void) {
u8_t init_version = CURRENT_VERSION;

char prefix_str[NET_IPV6_ADDR_LEN + 1];
struct in6_addr prefix;
u8_t prefix_len;

printk("RPL root node starting\n");

struct net_if *iface = net_if_get_default();
if (!iface) {
printk("Interface is NULL\n");
printk("Failed to setup RPL root node\n");
return;
}

// Read prefix from KConfig and parse it
memset(prefix_str, 0, sizeof(prefix_str));
memcpy(prefix_str, CONFIG_NET_RPL_PREFIX, min(strlen(CONFIG_NET_RPL_PREFIX), NET_IPV6_ADDR_LEN));

char *slash = strstr(prefix_str, "/");
if (!slash) {
prefix_len = 64;
} else {
*slash = '\0';
prefix_len = atoi(slash + 1);
}

if (prefix_len == 0) {
printk("Invalid prefix length %s", slash + 1);
return;
}

if (net_addr_pton(AF_INET6, prefix_str, &prefix) < 0) {
printk("Invalid IPv6 prefix %s", prefix_str);
return;
}

// Check the current version
if (CURRENT_VERSION == 0) {
// case 0 - call init
init_version = net_rpl_lollipop_init();
} else if (CURRENT_VERSION > 0) {
// case > 0 - increment
net_rpl_lollipop_increment(&init_version);
} else {
printk("CURRENT_VERSION should be greater or eqaul to 0");
return;
}

// Setup the root node
struct net_rpl_dag *dag = net_rpl_set_root_with_version(iface, CONFIG_NET_RPL_DEFAULT_INSTANCE, &prefix, init_version);

if (!dag) {
printk("Cannot set root node");
return;
}

bool ret = net_rpl_set_prefix(iface, dag, &prefix, prefix_len);
if (!ret) {
printk("Cannot set prefix %s/%d", prefix_str, prefix_len);
return;
}
}
'''

Most part of the code are based in pull request #980 and #5035, except version update handling, which I do manually.

The leaf node will run an empty main, I'll do the validation just pinging between the nodes using net shell.

On KConfig definitions for root node I setup RPL, 6LoWPAN and uart_pipe driver for 802.15.4:
'''
CONFIG_NET_RPL=y
CONFIG_NET_DEBUG_RPL=y
CONFIG_NET_RPL_GROUNDED=y
CONFIG_NET_RPL_MAX_DAG_PER_INSTANCE=1
CONFIG_NET_RPL_PREFIX="2001:db8::1/64"

# IPv6 (L3)
CONFIG_NET_IPV6=y

# 6LoWPAN (L2 - Adaptation Layer)
CONFIG_NET_6LO=y

# 802.15.4 (L2)
CONFIG_NET_L2_IEEE802154=y
CONFIG_NET_L2_IEEE802154_FRAGMENT=y

# 802.15.4 (L1)
CONFIG_IEEE802154_UPIPE=y

# Enabled Shell Extensions
CONFIG_NET_SHELL=y
CONFIG_NET_L2_IEEE802154_SHELL=y

# Disable default Ethernet interface
CONFIG_NET_SLIP_TAP=n

# Application Settings
CONFIG_NET_APP_SETTINGS=y
CONFIG_NET_APP_MY_IPV6_ADDR="2001:db8::1"
'''

In leaf node:
'''
CONFIG_NET_RPL=y
CONFIG_NET_DEBUG_RPL=y
CONFIG_NET_RPL_MAX_DAG_PER_INSTANCE=1

# IPv6 (L3)
CONFIG_NET_IPV6=y

# 6LoWPAN (L2 - Adaptation Layer)
CONFIG_NET_6LO=y

# 802.15.4 (L2)
CONFIG_NET_L2_IEEE802154=y
CONFIG_NET_L2_IEEE802154_FRAGMENT=y

# 802.15.4 (L1)
CONFIG_IEEE802154_UPIPE=y

# Enabled Shell Extensions
CONFIG_NET_SHELL=y
CONFIG_NET_L2_IEEE802154_SHELL=y

# Disable default Ethernet interface
CONFIG_NET_SLIP_TAP=n
'''

This way, I was able to run the example fine. The root published the prefix in DIO messages, the leaf node joined the DAG with DAO and I managed to ping between hosts using net shell.

My problems started when I tried to simulate a global repair scenario, rebooting the root node. To achieve this, it was necessary to modify some environments configurations.

To setup the QEMU environment I created the pipes manually and disabled removing/creation commands from zephyr/cmake/qemu/CMakeLists.txt in QEMU_NET_STACK session. This way when the 'server' node is rebooted the connection is not lost in the 'client' caused by the pipes recreation.

Also needed to modify get_mac() function from ieee802154_uart_pipe driver to assure that the MAC address assigned to the root node will be always the same:
'''
static inline u8_t *get_mac(struct device *dev)
{
struct upipe_context *upipe = dev->driver_data;


upipe->mac_addr[0] = 0x00;
upipe->mac_addr[1] = 0x10;
upipe->mac_addr[2] = 0x20;
upipe->mac_addr[3] = 0x30;

#if defined(CONFIG_NET_RPL_GROUNDED)
upipe->mac_addr[4] = 0xAA;
upipe->mac_addr[5] = 0xAA;
upipe->mac_addr[6] = 0xAA;
upipe->mac_addr[7] = 0xAA;
#else
UNALIGNED_PUT(sys_cpu_to_be32(sys_rand32_get()),
      (u32_t *) ((void *)upipe->mac_addr+4));
#endif

return upipe->mac_addr;
}
'''

Now I run both applications and wait the network to be configured. After that, I kill the root node, update the constant CURRENT_VERSION in main.c to 240, recompile and rerun it.

The leaf node receives the DIO messages from the root with the new version and and trigger the global repair. During this process it removes the old neighbors/parents and try to setup the new one.

'''
[net/rpl] [DBG] handle_dio: (0x20000558): Received DODAG Information Object from fe80::210:2030:aaaa:aaaa to ff02::1a
[net/rpl] [DBG] handle_dio: (0x20000558): Incoming DIO len 72 id 30 ver 241 rank 256
[net/rpl] [DBG] handle_dio: (0x20000558): Incoming DIO dag_id 2001:db8::1 pref 0
[net/rpl] [DBG] handle_dio: (0x20000558): DIO option 4 length 14
[net/rpl] [DBG] handle_dio: (0x20000558): DAG conf dbl 8 min 12 red 10 maxinc 1792 mininc 256 ocp 1 d_l 255 l_u 65535
[net/rpl] [DBG] handle_dio: (0x20000558): DIO option 8 length 30
[net/rpl] [DBG] handle_dio: (0x20000558): Prefix 2001:db8::/64
[net/rpl] [DBG] net_rpl_process_dio: (0x20000558): Global repair
[net/rpl] [DBG] net_rpl_process_dio: (0x20000558): Prefix announced in DIO
[net/rpl] [DBG] net_rpl_set_prefix: (0x20000558): Prefix is non-NULL, will announce this in DIOs
[net/rpl] [DBG] check_prefix: (0x20000558): Same prefix 2001:db8::/64 flags 0x40
[net/rpl] [DBG] remove_parents: (0x20000558): Removing parents minimum rank 0
[net/rpl] [DBG] net_rpl_remove_parent: (0x20000558): Removing parent fe80::210:2030:aaaa:aaaa [00:10:20:30:AA:AA:AA:AA]
[net/rpl] [DBG] net_rpl_nullify_parent: (0x20000558): Removing default route fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_dao_send: (0x20000558): Send DAO with prefix 2001:db8::210:2030:9b:9856 from fe80::210:2030:9b:9856 to fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): Preferred parent not set
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): It used to be fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_nullify_parent: (0x20000558): Nullifying parent fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] nbr_free: (0x20000558): nbr 0x200062b0
[net/rpl] [DBG] net_rpl_neighbor_data_remove: (0x20000558): Neighbor 0x200062b0 removed
[net/rpl] [DBG] net_rpl_mrhof_reset: (0x20000558): Reset MRHOF
[net/rpl] [DBG] net_rpl_add_parent: (0x20000558): Add parent fe80::210:2030:aaaa:aaaa [00:10:20:30:AA:AA:AA:AA]
[net/rpl] [DBG] nbr_add: (0x20000558): nbr linking failure (-69)
[net/rpl] [DBG] nbr_free: (0x20000558): nbr 0x200062b0
[net/rpl] [DBG] net_rpl_neighbor_data_remove: (0x20000558): Neighbor 0x200062b0 removed
[net/rpl] [DBG] net_rpl_add_parent: (0x20000558): Cannot add RPL neighbor
[net/rpl] [DBG] global_repair: (0x20000558): Failed to add a parent during the global repair
[net/rpl] [DBG] global_repair: (0x20000558): Participating in a global repair version 241 rank 65535
'''

I think it should send a DAO message to the root to rejoin the network if everything is ok, but as we can see in the log it doesn't went right.

I tried to discover the reason why it was unable to add the parent, starting from nbr_add(). I reached to net_nbr_link() function from nbr.c and clearly it failed because of idx check (-EALREADY = -69):
'''
if (nbr->idx != NET_NBR_LLADDR_UNKNOWN) {
return -EALREADY;
}
'''

I don't understand properly the neighbor structures and organization from zephyr to reach any conclusion here, but seems the neighbor passed as argument to net_nbr_link() is not properly cleared as the function expects.

After expending some time on gdb, I verified that the neighbor passed as an argument is the same which was removed right before global repair process. This brings me to net_rpl_neighbor_data_remove() function from rpl.c, which just prints a message and doesn't clear nbr.

Based on this I did a stupid test adding a line to net_rpl_neighbor_data_remove(), just to check what would happen: 
'''
nbr->idx = 0xff;
'''

After rerunning the case I got the RPL network restablished.

'''
[net/rpl] [DBG] handle_dio: (0x20000558): Received DODAG Information Object from fe80::210:2030:aaaa:aaaa to ff02::1a
[net/rpl] [DBG] handle_dio: (0x20000558): Incoming DIO len 72 id 30 ver 241 rank 256
[net/rpl] [DBG] handle_dio: (0x20000558): Incoming DIO dag_id 2001:db8::1 pref 0
[net/rpl] [DBG] handle_dio: (0x20000558): DIO option 4 length 14
[net/rpl] [DBG] handle_dio: (0x20000558): DAG conf dbl 8 min 12 red 10 maxinc 1792 mininc 256 ocp 1 d_l 255 l_u 65535
[net/rpl] [DBG] handle_dio: (0x20000558): DIO option 8 length 30
[net/rpl] [DBG] handle_dio: (0x20000558): Prefix 2001:db8::/64
[net/rpl] [DBG] net_rpl_process_dio: (0x20000558): Global repair
[net/rpl] [DBG] net_rpl_process_dio: (0x20000558): Prefix announced in DIO
[net/rpl] [DBG] net_rpl_set_prefix: (0x20000558): Prefix is non-NULL, will announce this in DIOs
[net/rpl] [DBG] check_prefix: (0x20000558): Same prefix 2001:db8::/64 flags 0x40
[net/rpl] [DBG] remove_parents: (0x20000558): Removing parents minimum rank 0
[net/rpl] [DBG] net_rpl_remove_parent: (0x20000558): Removing parent fe80::210:2030:aaaa:aaaa [00:10:20:30:AA:AA:AA:AA]
[net/rpl] [DBG] net_rpl_nullify_parent: (0x20000558): Removing default route fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_dao_send: (0x20000558): Send DAO with prefix 2001:db8::210:2030:9c:475a from fe80::210:2030:9c:475a to fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): Preferred parent not set
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): It used to be fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_nullify_parent: (0x20000558): Nullifying parent fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] nbr_free: (0x20000558): nbr 0x200062b0
[net/rpl] [DBG] net_rpl_neighbor_data_remove: (0x20000558): Neighbor 0x200062b0 removed
[net/rpl] [DBG] net_rpl_mrhof_reset: (0x20000558): Reset MRHOF
[net/rpl] [DBG] net_rpl_add_parent: (0x20000558): Add parent fe80::210:2030:aaaa:aaaa [00:10:20:30:AA:AA:AA:AA]
[net/rpl] [DBG] nbr_add: (0x20000558): [0] nbr 0x200062b0 IPv6 fe80::210:2030:aaaa:aaaa ll 00:10:20:30:AA:AA:AA:AA iface 0x200067a0
[net/rpl] [DBG] net_rpl_add_parent: (0x20000558): [0] nbr 0x200062b0 parent 0x200062c4
[net/rpl] [DBG] global_repair: (0x20000558): Starting global repair
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): Preferred parent fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): It used to be not set
[net/rpl] [DBG] net_rpl_set_default_route: (0x20000558): Adding default route through fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_select_dag: (0x20000558): Changed preferred parent, rank changed from 768 to 768
[net/rpl] [DBG] schedule_dao: (0x20000558): Scheduling DAO timer 4800 ms in the future
[net/rpl] [DBG] dao_timer: (0x20000cb0): Sending DAO iface 0x200067a0
[net/rpl] [DBG] net_rpl_dao_send: (0x20000cb0): Send DAO with prefix 2001:db8::210:2030:9c:475a from fe80::210:2030:9c:475a to fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_link_neighbor_callback: (0x2000060c): Neighbor link callback triggering update
[net/rpl] [DBG] handle_dao_ack: (0x20000558): Received Destination Advertisement Object Ack from fe80::210:2030:aaaa:aaaa to fe80::210:2030:9c:475a
[net/rpl] [DBG] handle_dao_ack: (0x20000558): Received a DAO ACK with seq number 244(244) status 0 from fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] handle_dao_ack: (0x20000558): Status ACK
'''

Clearly my approach wasn't correct, I don't even understand properly the neighbor dynamics. Did I miss something in my setup which might have caused this behavior? Or there are something wrong on neighbor management?

Thank you!

--
Att,
Pedro Martucci
---
Gerência de Tecnologias de Controle e Inteligência de Sistemas
CPqD - Diretoria de Tecnologias de Comunicação
Tel.: +55 19 3705-5995


Re: [Zephyr-devel] button1 GPIOTE interrupt enable for NRF52840_PCA10056

Carles Cufi
 

Hi Vikrant,

 

Why don’t you use the existing GPIO driver?

https://github.com/zephyrproject-rtos/zephyr/blob/master/drivers/gpio/gpio_nrf5.c

 

It works with the button sample.

 

Regards,

 

Carles

 

From: zephyr-devel-bounces@... [mailto:zephyr-devel-bounces@...] On Behalf Of Vikrant More
Sent: 28 November 2017 14:32
To: zephyr-devel@...; zephyr-users@...
Subject: [Zephyr-devel] button1 GPIOTE interrupt enable for NRF52840_PCA10056

 

Hello,

I want to enable GPIOTE interrupt for for Button1. For that I write

void GPIOTE_IRQHandler(void *arg)
{

 

  if(NRF_GPIOTE->EVENTS_IN[0]!=0)
  {
    NRF_GPIOTE->EVENTS_IN[0]=0;

    NRF_P0->OUT ^= (1<<16);

  }
}

void gpio_init(void)
{

 

 

  NRF_P0->DIR |= 0x0001E000;           // for LEDs
  NRF_P0->OUTSET |= 0x0001E000;   // for LEDs

 

 

 

  NRF_P0->PIN_CNF[11]=0x0000000C;   // for making P0.11 as input

  NRF_GPIOTE->INTENSET |= 0x00000001;                         
  NRF_GPIOTE->CONFIG[0] |= 0x00000001 | (11<<8) | (2<<16);

  NVIC_EnableIRQ(GPIOTE_IRQn);
}

 

I am able to compile code successfully & as per my understanding after pressing Button1,

Led4 should toggle on every click.

 

But I think interrupt is not get executed.

 

 

Could anybody help me to solve this issue ?

 

 

How to rewrite logic as per it ? how to modify prj.conf ?

 

 

Thank You!!


button1 GPIOTE interrupt enable for NRF52840_PCA10056

Vikrant More <vikrant8051@...>
 

Hello,
I want to enable GPIOTE interrupt for for Button1. For that I write

void GPIOTE_IRQHandler(void *arg)
{
 
  if(NRF_GPIOTE->EVENTS_IN[0]!=0)
  {
    NRF_GPIOTE->EVENTS_IN[0]=0;

    NRF_P0->OUT ^= (1<<16);

  }
}

void gpio_init(void)
{


  NRF_P0->DIR |= 0x0001E000;           // for LEDs
  NRF_P0->OUTSET |= 0x0001E000;   // for LEDs

 

  NRF_P0->PIN_CNF[11]=0x0000000C;   // for making P0.11 as input

  NRF_GPIOTE->INTENSET |= 0x00000001;                         
  NRF_GPIOTE->CONFIG[0] |= 0x00000001 | (11<<8) | (2<<16);

  NVIC_EnableIRQ(GPIOTE_IRQn);
}

I am able to compile code successfully & as per my understanding after pressing Button1,
Led4 should toggle on every click.

But I think interrupt is not get executed.


Could anybody help me to solve this issue ?


How to rewrite logic as per it ? how to modify prj.conf ?


Thank You!!

2381 - 2400 of 2705