How to Send a broadcast packet in a RDC layer in Contiki? - contiki

I'm trying to code my own RDC layer in contiki, with the PW-MAC protocol.
I was wondering how to send a broadcast in this layer because there will have no network and no transport layer.
The function i have to use will be:
NETSTACK_RDC.send(mac_callback_t sent, void *ptr)
But I really don't know what mac_callback_t and ptr is... The examples in sources use udp for the broadcast so it will be very annoying if i have to implement a transport layer.
Thanks for your answers

You should check a bit the doc and the code, that could help you a lot.
ptr is a data pointer (void*). So its your data to send.
mac_call_back_t is clear : to trigger a callback to the mac layer. (a function pointer)
To send a broadcast, just send to FFF address. (you must change the address with packetbuf, check the doc of packetbuf. (a good link for packet_buf : http://anrg.usc.edu/contiki/index.php/Packetbuffer_Basics)
Check the broadcast_conn in Rime to understand how broadcast are done and to have an example.

RDC stands for "radio duty cycling". The RDC layer uses radio functions directly, so sending a packet could be as simple as calling NETSTACK_RADIO.send(packetbuf_hdrptr(), packetbuf_totlen()).
The Contiki network stack has this layering structure:
NETWORK layer -> MAC layer -> RDC layer -> RADIO layer.
(In recent versions there's an additional LLSEC layer between NETWORK and MAC layers.)
So an implementation of RDC layer API uses the RADIO layer API and is called by / reports to MAC layer API. You can look at core/net/mac/nullrdc.c to see how to implement a simple RDC driver.
As you noted, NETSTACK_RDC.send(mac_callback_t sent, void *ptr) takes two parameters. The first is of callback type which you need to call after finishing the sending, the second is user data you need to pass to the to the callback.
The callback is typedef in net/mac/mac.h as:
typedef void (* mac_callback_t)(void *ptr, int status, int transmissions);
ptr is the user data pointer passed to NETSTACK_RDC.send;
status is MAC status code, such as MAC_TX_OK - the result of the
transmission;
transmissions is the number of transmissions.

Related

ESP8266 5v Relay USB Disconnection issue

Issue
-When using the ESP8266 wired up in this way it will randomly disconnect the USB interface when it powers the relay. It may then re-connect but is sporadic.
-The code can be viewed below, but essentially the relay is powered for 300ms then waits 10 seconds to loop.
Wiring Diagram https://i.stack.imgur.com/4mycx.png
Tests:
I have swapped out the relay, pump, ESP8266, aswell as re-wiring the circuit multiple times to check for a short. I also have a integer incrementing every loop cycle, when the ESP8266 is able to re-connect it will print this variable, which shows the board is not crashing:
Serial output
https://i.stack.imgur.com/ziM8g.png
I then modified the diagram so the 5v power was not in parallel, but where two different power sources, one for the ESP8266 and one for the pump circuit, however the same issue was observed:
Test Wiring Diagram https://i.stack.imgur.com/7S0aP.png
Question:
Why does the USB disconnect when sending the control signal to the relay?
Is there a way to mitigate this?
Code:
int relayInput = 5; // the input to the relay pin
int debug_test = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(relayInput, OUTPUT); // initialize pin as OUTPUT
}
void loop() {
// put your main code here, to run repeatedly:
debug_test ++ ;
Serial.println(debug_test);
digitalWrite(relayInput, HIGH); // turn relay on
Serial.println("Water on!");
delay(300);
digitalWrite(relayInput, LOW); // turn relay off
Serial.println("Water off!");
Serial.println("Waiting 10 seconds");
delay(10000);
}
Parts:
Pump - https://www.ebay.co.uk/itm/Mini-Water-Pump-DC-3V-4-5V-Fish-Tank-Fountain-Aquarium-Submersible-White-Parts/174211676084?hash=item288fd337b4:g:128AAOSwfQteYWF3
ESP8255 - https://www.amazon.co.uk/gp/product/B07F5FJSYZ/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1
Relay - https://www.amazon.co.uk/gp/product/B07BVXT1ZK/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1
Ok, so researching in to this, it seems when the pump is on it pulls more current (amps) than the PC can provide.
This will be used connected to a external power source which should supply enough current to it, however I also wanted the flexibility to connect it to a PC with a serial connection to troubleshoot.
So in the end something like this:
https://i.stack.imgur.com/MKD1h.png
You are driving a 5v relay module with 3.3v output, which works perfectly for some people but it depends on the relay module and the board, this might be the problem. or the relay draws more than 12mA which is the maximum current can the ESP8266's GPIO deliver.
so I suggest you use an external power source for the relay and control it through the pin (D1 in your case).
Or just use a generic 5v relay with an external 5v power source and control it using a transistor, here is a circuit.
Additional information: https://electronics.stackexchange.com/questions/213051/how-do-i-use-a-5v-relay-with-a-3-3v-arduino-pro-mini?

How to sense channel in Contiki?

What is the function call or set of instructions required to perform channel sensing in MAC layer of Contiki?
I want to test custom MAC protocols, so for example in CSMA, channel sensing is required before transmission.
I have gone through 'contiki/core/net/mac/csma.c' to see how they have done channel sensing. But I could only see scheduling of queue packets and status checks.
How are they checking if channel is busy before transmission?
You can do this:
if(NETSTACK_RADIO().channel_clear()) {
printf("channel not busy\n");
} else {
printf("channel busy\n");
}
The channel check is implemented in the radio driver. Contiki has platform independent radio API. The actual, platform-specific driver is available through NETSTACK_RADIO API, as demonstrated above. The check is used b the RDC (radio duty cycling) layer, for example, ContikiMAC.

TinyOs nesc Packet acknowledge

I want to write a mote-mote radio communication program, and want the receiver acknowledges back to the sender. I know the PacketAcknowledgements is recommended, but there are some questions I'm not sure about this interface.
1. If I use it in the sender mote,should i also uses interface Receive in the module of the sender mote
2. Should I write extra code in the receiver mote? Should I use interface PacketAcknowledgements too?
3. command error_t requestAck(message_t *msg) and command bool wasAcked(message_t *msg) should be used when and where
No.
No.
You need to call requestAck on a packet you're about to send just before calling send from interface AMSend or Send. Be sure to check an error code returned by requestAck, because FAIL indicates that the communication layer doesn't support synchronous acknowledgements (it depends on the radio chip and driver you use). Once the packet is sent, i.e., inside event sendDone (or later), call wasAcked, which returns true if the packet was acknowledged by the receiver.
More info in:
https://github.com/tinyos/tinyos-main/blob/master/tos/interfaces/PacketAcknowledgements.nc

QNX MsgReceive Pulse

I have a problem because I don't know how _pulse receiving works. If I have my data struct
typedef struct _my_data {
msg_header_t hdr;
int data;
} my_data_t;
and I am receiving only my msg I cant tell if it is a pulse
my_data_t msg;
...
rcvid = MsgReceive(g_Attach->chid, &msg, sizeof(msg), NULL);
when rcvid = 0 BUT how a program knows that it need to send _pulse in a form of msg (struct that I defined) or else how does it work. In addition is _IO_CONNECT a pulse? If yes why doesn't it have rcvid==0? - according to http://www.qnx.com/developers/docs/6.3.2/neutrino/lib_ref/n/name_attach.html
1 - _IO_CONNECT is not used for pulse. Its used for connect system call to resource managers. Example system calls are open(), close(), etc.
2 - You need to know whether the server or client is waiting on pulse message or not. For pulse message the blocking function in the resource manager will be MsgReceivePulse() and the client will use MsgSendPulse().
MsgSend() is used for normal message and MsgSendPulse() is for sending pulse message.
Similarly MsgReceive() is used for receiving normal message and MsgReceivePulse() is used for receiving pulse messages. Please refer to the QNX documents for more detailed description.
Both variants have different parameters like the functions for pulse messages do not have any parameter for return data because pulses are non blocking small messages which do not block for any reply but functions for normal messages have parameters for receive data.
You need to create channel and connection, for example
chid=ChannelCreate(0);
int pid=getpid();
coid=ConnectAttach(0, pid, chid, 0, 0);
and attach channel to connection.............
Then if you have two threads...............from one thread you can to call MsgSend function, for example MsgSend(coid, &(message), sizeof(message), &rmsg, sizeof(rmsg)); and in the other thread rcvid=MsgReceive(chid, (void*)&message, sizeof(message),NULL);

path of packets through network stack

I'm trying to study and understand operations of the Linux tcp/ip stack, specifically how 'ping' sends packets down and receives them.
Ping creates raw socket in AF_INET family, therefore I placed printk in inet_sendmsg() at net/ipv4/af_inet.c to print out the socket protocol name (RAW, UDP etc.) and the address of protocol specific sendmsg function which correctly appears to be raw_sendmsg() from net/ipv4/raw.c
Now, I'm sending a single packet and observe that I'm getting printk form inet_sendmsg() twice.This puzzles me -- is it normal (has something to do with interrupts etc. ?) or there's something broken in the kernel?
Platform - ARM5te, kernel 2.6.31.8
Looking forward to hearing from you !
Mark

Resources