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);
Related
I am using CANalyzer.
I am transmitting CAN message using Interactive Generator block. I use IG to modify signals in transmitted message by hand.
I need to automaticaly calculate checksum (the last byte in the message) every time the message is sent. Checksum is calculated from all previous data bytes in the message (message is always 8 bytes long). There is no option in IG to do that.
I need:
Set signals by hand using IG.
Automatically calculate value of the last data byte according to values of preceding data bytes.
I tried to write simple code in CAPL but without success.
I put CAPL Program node after the IG node in the Configuration window and wrote on message event in CAPL script:
on message FooMsg
{
message FooMsg msg1; // FooMsg is name of message in database
msg1 = this; // copy message from IG to temporary variable
// this.byte(7) = 0x11; // not posibble, compiler warning
msg1.byte(7) = 0x11; // constant value just for test
output(msg1); // send message
}
The message is transmitting but the Tx period set in IG is not respected (message is transmitted as fast as possible).
I thought I catch the message generated from IG, modify it and send to CAN bus.
Finally, I redesigned the whole stuff as VioletVynil recommended.
I created panels, add system variables and hooked them to controls on panels, wrote some code in CAPL for calculating checksum and periodic transmit of the message and it runs! Without any problems! And yes additional CRC on the payload is used for additional safety (railway application). I didn't designed communication protocol, I just got it.
Strange but I cannot find any information on that: if I write a [large] message to the WebSocket stream on iOS and the execution gets back to my code, is the message already sent or somehow buffered?
I'm using Starscream library but it just uses CFStream-s.
Looking at the source code for the Starscream library mentioned, the library appends the send operation to a NSOperation queue:
private func dequeueWrite(..) {
...
writeQueue.addOperation(operation)
}
and then immediately returns.
So when the one of the send methods returns, for example:
open func write(data: Data, completion: (() -> ())? = nil)
The message will not yet have been sent.
But as you can see you can pass a completion block to this method, that will be called when the whole message has been written to the underlying output stream. Note that this doesn't tell you anything about whether the message has actually been sent on the network, or if the sender has received it successfully.
To know if the sender has received and processed the message successfully, you need to wait for a response message - that is something you need to define in your application protocol.
Before using the Starscream library in production, you might want to report/fix some issues in it. While reviewing the send mechanism I noticed that if the OutputStream buffer is full on WebSocket.swift line 1254 the library tries sending the rest of the buffer in a busy loop rather than waiting for a hasSpaceAvailable event. This may waste a lot of CPU cycle if you send a large message.
Also, it looks like the case when stream.write returns 0, indicating that the output buffer is full, is incorrectly handled as an error.
Probably it use
func CFWriteStreamWrite(_ stream: CFWriteStream!,
_ buffer: UnsafePointer<UInt8>!,
_ bufferLength: CFIndex) -> CFIndex
the write call return "The number of bytes successfully written, 0 if the stream has been filled to capacity (for fixed-length streams), or -1 if either the stream is not open or an error occurs."
So yes, they are buffered. But I think that is the only option, a write function need to have the buffer because every socket have a max buffer zsize
I am working with Rime, more specifically with the runicast example. Once a message is received i store it in a linked list, then i post an event to a process which is in charge of extracting messages from the linked list and processing them. My code is something like this:
static void recv_runicast(struct runicast_conn *c,
const linkaddr_t *from, uint8_t seqno)
{
/*code to insert the message into the linked list*/
...
/*Post an event to the process which extracts messages from the linked list */
process_post(&extract_msg_from_linked_list, PROCESS_EVENT_CONTINUE, NULL);
}
My question is: Is it safe to use process_post within the callback function recv_runicast? or should i use process_poll?
Thanks in advance
Yes, it's safe. The network stack operations are done in process context, and Contiki processes are not preemptive. So pretty much any process-related operations are "safe".
The main differences between process_post and process_poll is that the former will put a new event in the process event buffer, while the latter will simply set a flag. So the second options is slightly more efficient. Also, in theory the event buffer can get full and events start to get lost, but that's very unlikely to be a problem.
I would use none of these functions at all, but do the processing directly in the callback to simplify the execution flow.
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.
I trigger the scan with following code
struct nl_msg *msg = nlmsg_alloc();
struct nlmsghdr *hdr;
struct genlmsghdr cmd = { .cmd = NL80211_CMD_TRIGGER_SCAN };
struct nl_sock *sock = nl_socket_alloc();
int dev = if_nametoindex("wlan0");
nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev);
hdr = nlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, NLMSG_NOOP, 0, 0);
memcpy(nlmsg_data(hdr), &cmd, sizeof(cmd));
nl_send_auto(sock, msg);
Now, how should i know when scan is finished, and how can i get it? In all places i have been searching so far, there is "You will receive NL80211_CMD_NEW_SCANS notification on "scan" multicast group", How should i subscribe to it? i registered my callback, tried
nl_socket_add_memberships(sock, RTN_MULTICAST);
and after that listen for messages in while with
while (1)
nl_recvmsgs_default(sock);
but nothing happened, so: if you had enough patience to read up to this point, please help me with 2 questions
1) How do i know when scan is finished(how to subscribe on this notifications, or read them etc.)
2) How can i read messages after notifications received(method as i understand it below)
To read scanned data i need to send message similar to one that triggers scan, but with message NL80211_CMD_GET_SCAN, and after that data will be stored in nl_socket's payload, am i right?
send a NL80211_CMD_TRIGGER_SCAN to start a scan off. (one after another will fail)
After sending, then listen out for the scan to complete when you get a NL80211_CMD_NEW_SCAN_RESULTS.
a NL80211_CMD_GET_SCAN command to ask for the results.
You will get one message back for every station found, so be ready to handle multiple messages.
NL80211_CMD_TRIGGER_SCAN to scan off
listen to NL80211_CMD_NEW_SCAN_RESULTS
NL80211_CMD_GET_SCAN command to ask for the results
should get one message back for every station found