Difference between revisions of "Packetbuffer Basics"

From Contiki
Jump to: navigation, search
(Some Important variables)
(Some Important variables)
Line 174: Line 174:
 
'''bufptr''' is used to points to a beginning location of the packet payload in the buffer.
 
'''bufptr''' is used to points to a beginning location of the packet payload in the buffer.
  
'''hdrptr''' point to the first character of the header of a packet. The header is stored in the slots with number starting from '''hdrptr''' to '''PACKETBUF_HDR_SIZE-1'''. Keep in mind that the first location of an array is numbered as 0. Therefore, the header is stored in '''packetbuf[hdrptr]''' to '''packetbuf[PACKETBUF_HDR_SIZE-1]'''. For example say i.e say the PACKETBUF_HDR_SIZE is 8 and hdrptr=5 then '''packetbuf[5:8]''' contains the header.
+
'''hdrptr''' point to the first character of the header of a packet. The header is stored in the slots with number starting from '''hdrptr''' to '''PACKETBUF_HDR_SIZE-1'''. Keep in mind that the first location of an array is numbered as 0. Therefore, the header is stored in '''packetbuf[hdrptr]''' to '''packetbuf[PACKETBUF_HDR_SIZE-1]'''. For example say i.e say the PACKETBUF_HDR_SIZE is 9 and hdrptr=5 then '''packetbuf[5:8]''' contains the header.
  
 
[[File:Header.jpg]]
 
[[File:Header.jpg]]

Revision as of 23:11, 4 November 2014

Back to Contiki Tutorials


Introduction

This tutorial is a introduction to different operations on the packetbuf on ContikiOS 2.7. We will also cover brief details about each of the functions and how they work.

You will learn

Through this tutorial you will learn about different funcions and usage components of packetbuf. This will help you in any projects since packetpuf is necessary for any networking project.


Source Codes

~/contiki-2.7/core/net/packetbuf.c

~/contiki-2.7/core/net/packetbuf.h


Description of the Parameters and Initializations

Packet Attributes

In this section we will discuss the details about different attributes of the packet in packet buffer.

struct packetbuf_attr packetbuf_attrs[PACKETBUF_NUM_ATTRS];
struct packetbuf_addr packetbuf_addrs[PACKETBUF_NUM_ADDRS];

These two structures are used to store the attributes of the packet and the addresses related to the packet i.e. source and destination address. The respective structures are defined as follows.

typedef uint16_t packetbuf_attr_t;

struct packetbuf_attr {
/*   uint8_t type; */
  packetbuf_attr_t val;
};
struct packetbuf_addr {
/*   uint8_t type; */
  rimeaddr_t addr;
};

Therefore packetbuf_attrs is an array of packets attributes. The array size is PACKETBUF_NUM_ATTRS. Similarly packetbuf_addrs is an array of packet addresses. The array size is PACKETBUF_NUM_ADDRS.

The sizes are defined as follows where PACKETBUF_ATTR_MAX=28:

//  File:   ~/contiki-2.7/core/net/packetbuf.h
#define PACKETBUF_NUM_ADDRS 4
#define PACKETBUF_NUM_ATTRS (PACKETBUF_ATTR_MAX - PACKETBUF_NUM_ADDRS)

The reason behind such definition is that the PACKETBUF_ATTR_MAX also counts the packets's sender and receiver address as the packet's attribute.

The val field in the packetbuf_attr structure can be assigned any of the follwing values: Now, to set a attribute we have to call the following function. We have to supply with the type and the value:

static inline int
packetbuf_set_attr(uint8_t type, const packetbuf_attr_t val)
{
/*   packetbuf_attrs[type].type = type; */
  packetbuf_attrs[type].val = val;
  return 1;
}

The types are defined as follows

enum {
  PACKETBUF_ATTR_NONE,//or  integer value=0

  /* Scope 0 attributes: used only on the local node. */
  PACKETBUF_ATTR_CHANNEL,//or  integer value=1
  PACKETBUF_ATTR_NETWORK_ID,//or  integer value=2
  PACKETBUF_ATTR_LINK_QUALITY,//or  integer value=3
  PACKETBUF_ATTR_RSSI,//or  integer value=4
  PACKETBUF_ATTR_TIMESTAMP,//or  integer value=5
  PACKETBUF_ATTR_RADIO_TXPOWER,//or  integer value=6
  PACKETBUF_ATTR_LISTEN_TIME,//or  integer value=7
  PACKETBUF_ATTR_TRANSMIT_TIME,//or  integer value=8
  PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS,//or  integer value=9
  PACKETBUF_ATTR_MAC_SEQNO,//or  integer value=10
  PACKETBUF_ATTR_MAC_ACK,//or  integer value=11

  /* Scope 1 attributes: used between two neighbors only. */
  PACKETBUF_ATTR_RELIABLE,//or  integer value=12
  PACKETBUF_ATTR_PACKET_ID,//or  integer value=13
  PACKETBUF_ATTR_PACKET_TYPE,//or  integer value=14
  PACKETBUF_ATTR_REXMIT,//or  integer value=15
  PACKETBUF_ATTR_MAX_REXMIT,//or  integer value=16
  PACKETBUF_ATTR_NUM_REXMIT,//or  integer value=17
  PACKETBUF_ATTR_PENDING,//or  integer value=18
  
  /* Scope 2 attributes: used between end-to-end nodes. */
  PACKETBUF_ATTR_HOPS,//or  integer value=19
  PACKETBUF_ATTR_TTL,//or  integer value=20
  PACKETBUF_ATTR_EPACKET_ID,//or  integer value=21
  PACKETBUF_ATTR_EPACKET_TYPE,//or  integer value=22
  PACKETBUF_ATTR_ERELIABLE,//or  integer value=23

  /* These must be last */
  PACKETBUF_ADDR_SENDER,//or  integer value=24
  PACKETBUF_ADDR_RECEIVER,//or  integer value=25
  PACKETBUF_ADDR_ESENDER,//or  integer value=26
  PACKETBUF_ADDR_ERECEIVER,//or  integer value=27
  
  PACKETBUF_ATTR_MAX //or  integer value=28
};

Therefore to choose an attribute you have to choose from the first 24 entries.e.g., packetbuf_set_attr(PACKETBUF_ATTR_RSSI,8) will set the RSSI attribute packet of the packet to be 8.

Similarly to get an attribute value we have to use following function

static inline packetbuf_attr_t
packetbuf_attr(uint8_t type)
{
  return packetbuf_attrs[type].val;
}

E.g. packetbuf_attr(PACKETBUF_ATTR_RSSI) will return the RSSI value associated with the packet.

Similarly to set address attributes we have to use the following function. Here type can be PACKETBUF_ADDR_SENDER, PACKETBUF_ADDR_RECEIVER, PACKETBUF_ADDR_ESENDER or PACKETBUF_ADDR_ERECEIVER i.e any value between 24-27. The value of PACKETBUF_ADDR_FIRST is 24.

static inline int
packetbuf_set_addr(uint8_t type, const rimeaddr_t *addr)
{
/*   packetbuf_addrs[type - PACKETBUF_ADDR_FIRST].type = type; */
  rimeaddr_copy(&packetbuf_addrs[type - PACKETBUF_ADDR_FIRST].addr, addr);
  return 1;
}

And to get the address attributes we have to use the following function.

static inline const rimeaddr_t *
packetbuf_addr(uint8_t type)
{
  return &packetbuf_addrs[type - PACKETBUF_ADDR_FIRST].addr;
}

Some Important variables

/* The declarations below ensure that the packet buffer is aligned on an even 16-bit boundary. On some platforms (most notably the
   msp430), having apotentially misaligned packet buffer may lead to problems when accessing 16-bit values. */
static uint16_t packetbuf_aligned[(PACKETBUF_SIZE + PACKETBUF_HDR_SIZE) / 2 + 1];
static uint8_t *packetbuf = (uint8_t *)packetbuf_aligned;

static uint8_t *packetbufptr;

where PACKETBUF_SIZE is the maximum size od the payload section of a packet and PACKETBUF_HDR_SIZE is the size of the header of a packet. packetbuf points to the array that stores the packet data. Note the conversion from uint16_t array structure to a uint8_t array structure. It is in uint8_t format because it is equal to the size of a character(8 bit), therefore each entry of the array can be used to store a character. The size of the buffer is PACKETBUF_SIZE + PACKETBUF_HDR_SIZE + 2. packetbufptr is a pointer used to operate on different positions of the packetbuf.

By default PACKETBUF_SIZE is 128 and PACKETBUF_HDR_SIZE is 48 (Defined in ~/contiki-2.7/core/net/packetbuf.h)

static uint16_t buflen, bufptr;
static uint8_t hdrptr;

buflen refers to the size of the packet payload in the packetbuf.

bufptr is used to points to a beginning location of the packet payload in the buffer.

hdrptr point to the first character of the header of a packet. The header is stored in the slots with number starting from hdrptr to PACKETBUF_HDR_SIZE-1. Keep in mind that the first location of an array is numbered as 0. Therefore, the header is stored in packetbuf[hdrptr] to packetbuf[PACKETBUF_HDR_SIZE-1]. For example say i.e say the PACKETBUF_HDR_SIZE is 9 and hdrptr=5 then packetbuf[5:8] contains the header.

Header.jpg

Description of the Functions

void packetbuf_clear(void)

This function clears the packetbuf and resets all internal state pointers (header size, header pointer, external data pointer). It is used before preparing a packet in the packetbuf.

                                 buflen = bufptr = 0;

This line resets the variable that points to the payload section.

                                 hdrptr = PACKETBUF_HDR_SIZE;
                                 packetbufptr = &packetbuf[PACKETBUF_HDR_SIZE];

These lines reset the header pointer to the end of the header section of the buffer which implies that the there is no header. It also sets the packetbufptr pointer to the first location of the array after the the header section which is also the beginning of the payload section.

Note that this function doesn't delete the content of the memory. It just resets the pointers. You should be careful about that while using this function in your code.

                                 packetbuf_attr_clear();

Now, this function clears all the attributes including the address fields of the buffer. The code is as follows

void
packetbuf_attr_clear(void)
{
  int i;
  for(i = 0; i < PACKETBUF_NUM_ATTRS; ++i) {
    packetbuf_attrs[i].val = 0;  // Reset the attribute value to 0 i.e NULL
  }
  for(i = 0; i < PACKETBUF_NUM_ADDRS; ++i) {
    rimeaddr_copy(&packetbuf_addrs[i].addr, &rimeaddr_null); // Reset the rime address values to 0 i.e NULL
  }
}

void packetbuf_clear_hdr(void)

This function only resets the header field of the packet buffer.This function resets all the internal state pointers pertaining to the header (header size, header pointer, but not external data pointer). It is used before after sending a packet in the packetbuf, to be able to reuse the packet buffer for a later retransmission.

                                               hdrptr = PACKETBUF_HDR_SIZE;

Similar the packet buffer clear operation, this line just reset the header field pointer to the end of header field of the buffer which therby implies that there is no header. It doesn't delete the content of the memory. You should be careful about that while coding.

void packetbuf_hdr_remove(int size)

It removes the first size number of entries of the header. Which is nothing but a pointer operation where the beginning pointer has to be set to point to the new beginning. The following code does exactly the same thing.

                                                    hdrptr += size;

It moves the header pointer upwards by size number of slots.