I want to send two different type of messages from server to client. I have created two functions data_signal()
and probe_signal()
for each of these two different messages.
The data_signal()
function will periodically send a defined message with an interval of CLOCK_SECOND * 1
to the client.
I use a timer for interval CLOCK_SECOND * 30
duration to periodically call probe_signal()
to send a different message to the client.
Currently the data_signal()
function is working as expected. However the probe_signal()
function is not sending its message to the client.
I have verified this by simply printing message at the client end and the "probe_signal()" message is not received.
Moreover, if I comment uip_udp_packet_send(conn, buf, strlen(buf));
line of data_signal()
then I am able to receive the message from probe_signal()
. I think this issue is happening because I am using the same UDP connection
Code:
#include "contiki.h"
#include "contiki-lib.h"
#include "contiki-net.h"
#define DEBUG DEBUG_FULL
#include "net/ip/uip-debug.h"
#include "net/ip/uiplib.h"
#include "net/ipv6/uip-icmp6.h"
#include <string.h>
#define SERVER_IP "fe80::9a07:2dff:fe3c:8d01" //"::"
#define CLIENT_PORT 61617
#define SERVER_PORT 61616
#define PING_TIMEOUT (CLOCK_SECOND / 4)
#define CLIENT_SEND_INTERVAL (CLOCK_SECOND * 1)
#define UDP_LEN_MAX 255
/*---------------------------------------------------------------------------*/
static uip_ipaddr_t server_addr;
static struct uip_icmp6_echo_reply_notification icmp_notification;
static uint8_t echo_received;
static struct uip_udp_conn *conn;
static struct etimer timer;
static char buf[UDP_LEN_MAX];
static uint16_t packet_counter;
static uint16_t probe_packet_counter;
static uint16_t actualSent_packet_counter;
static int flag;
/*---------------------------------------------------------------------------*/
PROCESS(ipv6_ble_client_process, "IPv6 over BLE - client process");
AUTOSTART_PROCESSES(&ipv6_ble_client_process);
/*---------------------------------------------------------------------------*/
void icmp_reply_handler(uip_ipaddr_t *source, uint8_t ttl,
uint8_t *data, uint16_t datalen)
{
PRINTF("echo response received\n");
echo_received = 1;
}
/*---------------------------------------------------------------------------*/
static void tcpip_handler(void)
{
}
/*---------------------------------------------------------------------------*/
static void
data_signal(void)
{
sprintf(buf, "Current packet count is: %04u!",packet_counter);
PRINTF("send message: <%s>\n", buf); /*This printf is commented for understanding the low level code*/
uip_udp_packet_send(conn, buf, strlen(buf));
packet_counter++;
}
static void probe_signal(void)
{
sprintf(buf, "%04u", probe_packet_counter);
uip_udp_packet_send(conn, buf, strlen(buf));
printf("Probe signal is sent");
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(ipv6_ble_client_process, ev, data)
{
static struct timer t;
PROCESS_BEGIN();
PRINTF("CC26XX-IPv6-over-BLE client started\n");
conn = udp_new(&server_addr, UIP_HTONS(SERVER_PORT), NULL);
udp_bind(conn, UIP_HTONS(CLIENT_PORT));
timer_set(&t, CLOCK_SECOND * 30);
etimer_set(&timer, CLIENT_SEND_INTERVAL);
while(1)
{
if(timer_expired(&t))
{
flag =1;
if(flag==1)
{
probe_signal();
timer_reset(&t);
printf("Timer is reset\n");
}
}
PROCESS_YIELD();
if((ev == PROCESS_EVENT_TIMER) && (data == &timer))
{
data_signal();
etimer_set(&timer, CLIENT_SEND_INTERVAL);
}
else if(ev == tcpip_event)
{
printf("TCPIP event occured\n");
tcpip_handler();
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
Can someone guide how to resolve this, it would be a great help.
I am able to resolve this issue by changing the code:
etimer
etimer
event and then called probe_signal()
.From Events and Scheduling from Documentation: Processes and events:
Contiki-NG is built on an event-based execution model, where processes typically perform chunks of work before telling the scheduler that they are waiting for an event, and thereby suspend execution. Such events can be the expiration of a timer, an incoming network packet, or a serial line message being delivered.
Processes are scheduled cooperatively, which means that each process is responsible for voluntarily yielding control back to the operating system without executing for too long. Hence, the application developer must make sure that long-running operations are split into multiple process schedulings, allowing such operations to resume at the point where they last stopped.
And from the section Pausing and yielding from the same document:
By contrast, PROCESS_YIELD() will yield control back to the scheduler without expecting to be scheduled again shortly thereafter. Instead, it will wait for an incoming event, similar to PROCESS_WAIT_EVENT_UNTIL(), but without a required condition argument.
A discussion of the Etimer library can be found at Timers in the contiki-os github repository:
The Contiki etimer library provides a timer mechanism that generate timed events. An event timer will post the event PROCESS_EVENT_TIMER to the process that set the timer when the event timer expires. The etimer library use clock_time() in the clock module to get the current system time.
Updated Code:
#include "contiki.h"
#include "contiki-lib.h"
#include "contiki-net.h"
#define DEBUG DEBUG_FULL
#include "net/ip/uip-debug.h"
#include "net/ip/uiplib.h"
#include "net/ipv6/uip-icmp6.h"
#include <string.h>
#define SERVER_IP "fe80::9a07:2dff:fe3c:8d01" //"::"
#define CLIENT_PORT 61617
#define SERVER_PORT 61616
#define PING_TIMEOUT (CLOCK_SECOND / 4)
#define CLIENT_SEND_INTERVAL (CLOCK_SECOND * 1)
#define PROBE_SIGNAL_INTERVAL (CLOCK_SECOND * 30)
#define UDP_LEN_MAX 255
/*---------------------------------------------------------------------------*/
static uip_ipaddr_t server_addr;
static struct uip_icmp6_echo_reply_notification icmp_notification;
static uint8_t echo_received;
static struct uip_udp_conn *conn;
static struct etimer timer,probe_timer;
static char buf[UDP_LEN_MAX];
static uint16_t packet_counter;
static uint16_t probe_packet_counter;
static uint16_t actualSent_packet_counter;
static int flag;
/*---------------------------------------------------------------------------*/
PROCESS(ipv6_ble_client_process, "IPv6 over BLE - client process");
AUTOSTART_PROCESSES(&ipv6_ble_client_process);
/*---------------------------------------------------------------------------*/
void icmp_reply_handler(uip_ipaddr_t *source, uint8_t ttl,
uint8_t *data, uint16_t datalen)
{
PRINTF("echo response received\n");
echo_received = 1;
}
/*---------------------------------------------------------------------------*/
static void tcpip_handler(void)
{
}
/*---------------------------------------------------------------------------*/
static void
data_signal(void)
{
sprintf(buf, "Current packet count is: %04u!",packet_counter);
PRINTF("send message: <%s>\n", buf); /*This printf is commented for understanding the low level code*/
uip_udp_packet_send(conn, buf, strlen(buf));
packet_counter++;
}
static void probe_signal(void)
{
sprintf(buf, "%04u", probe_packet_counter);
uip_udp_packet_send(conn, buf, strlen(buf));
printf("Probe signal is sent");
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(ipv6_ble_client_process, ev, data)
{
PROCESS_BEGIN();
PRINTF("CC26XX-IPv6-over-BLE client started\n");
conn = udp_new(&server_addr, UIP_HTONS(SERVER_PORT), NULL);
udp_bind(conn, UIP_HTONS(CLIENT_PORT));
etimer_set(&probe_timer, PROBE_SIGNAL_INTERVAL); // set up a timer event for calling probe_signal() function
etimer_set(&timer, CLIENT_SEND_INTERVAL); // set up a timer event for calling data_signal() function
while(1)
{
PROCESS_YIELD(); // yield waiting for an timer event or other event
if((ev == PROCESS_EVENT_TIMER) && (data == &timer))
{
// timer event received so process it and then reschedule again.
data_signal();
etimer_set(&timer, CLIENT_SEND_INTERVAL);
}
if((ev == PROCESS_EVENT_TIMER) && (data == &probe_timer))
{
// timer event received so process it and then reschedule again.
probe_signal();
etimer_set(&timer, PROBE_SIGNAL_INTERVAL);
}
else if(ev == tcpip_event)
{
printf("TCPIP event occured\n");
tcpip_handler();
}
}
PROCESS_END();
}