How to know when scan is finished - network-programming

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

Related

Is there a way to inject keyboard events from a command line application?

This might seem a little sketch, but I am trying to automate a minor inconvenience that I have.
Every day at the beginning of the day, I want to start a chat on skype with a certain group of people.
I created an app so I can just type chat daily at the command line and it will create the chat automatically. The issue is that it's just a blank chat and I need to start the chat with the same message. I want to be able to pass a -m flag to the app followed by the message that should be sent to everyone. The issue is being able to get that text into the skype chat.
Here are my thoughts on how this could be done:
Send Keyboard events so that the text entered into the text box and then sent in the chat.
Add the message to the clipboard, and subsequently paste the message. If I can't get it to send the text and I have to manually click [enter] I'm ok with that.
Lastly, if there's not a way to send keyboard events already, a much more involved approach would be to somehow emulate a keyboard to the system.
So basically I want to know if there's a way to control the clipboard of the system (copy/paste) or if there's a way to send keypresses to the system.
If you have any other ideas on how this, or if this, can be achieved, I'd like to hear.
Thanks so much in advance
Have a look at the win32 package, which has some bindings from the Win32 Windows Api to Dart, it has a ton of examples, but what you need should be something like this:
final kbd = KEYBDINPUT.allocate();
// Send the A key.
kbd.wVk = VK_A;
var result = SendInput(
1, Pointer.fromAddress(kbd.addressOf.address), sizeOf<KEYBDINPUT>());
if (result != 1) print('Error: ${GetLastError()}');
kbd.dwFlags = KEYEVENTF_KEYUP;
result = SendInput(
1, Pointer.fromAddress(kbd.addressOf.address), sizeOf<KEYBDINPUT>());
if (result != 1) print('Error: ${GetLastError()}');
(from https://github.com/timsneath/win32/blob/master/example/sendinput.dart#L20-L30)

When can i use SendChatMessage after logon?

After logon, i would like to send a chat message to the Guild channel.
I'm currently listening for events:
PLAYER_ENTERING_WORLD
GUILD_ROSTER_UPDATE
Once those have fired (in order), i'd like to send a chat message. However, it never sends.
Code:
print("Should_send")
SendChatMessage(msgToSend, "GUILD");
It's also worth noting that if i then trigger this manually, it works.
I do see the "Should_send" print statement appearing in the default chat window each time - as expected. I've also checked that "msgToSend" contains content - and is less than 255 characters.
So, when can i call SendChatMessage?
Ok, in order to be able to send a chat message to guild, you need to wait for the event "CLUB_STREAM_SUBSCRIBED" to fire.
This is due to the Guild channel becoming a "community" channel of sorts - previously, it seems this wasn't required.
So, adding an event listener:
frame:RegisterEvent("CLUB_STREAM_SUBSCRIBED");
Resolves the issue.
You will likely need to set a flag for the event, then print later on another event.
You can send chat messages any time after you see the welcome message or after the welcome message was posted. Which is pretty soon after you able to receive events from your frames.
Here is what I would do to complete a similar mission:
Just put your send code in a macro to test it first. Don't worry about timing the message until you see it work in a macro.
You can make your own print to send generic messages to the chat window which should always work similar to:
function MyPrint( msg, r, g, b, frame, id)
(frame or DEFAULT_CHAT_FRAME):AddMessage(msg, r or 1, g or 1, b or 0, id or 0)
end
-- put these in your event handlers
MyPrint("event PLAYER_ENTERING_WORLD")
MyPrint("event GUILD_ROSTER_UPDATE")
And use that for debugging instead.
You need to divide and conquer the problem, because there are so many things that could be wrong causing your issue, no one here can really have a definitive answer.
I know for sure that if you try to write to chat before the welcome message with print it at least used to not work. I remember spooling messages in the past until a certain event had fired then printing them.

How message reception order is modeled under Omnet++?

I read a lot about messages Sending/Reception under Omnet++, but currently i am asking my self about reception order under Omnet++.
Let say that:
I am using a WIFI network card
I want to send two messages from A to
B
The question is: If i send msg1 then msg2, is it possible that i receive msg2 before msg1 ?
Based on what i know and what i read, i guess that is not possible, but i will be greatfull if some one can confirm/invalidate it.
Thanks,
After reading properely Omnet++ documentation and by taking into account the evenemential model of the simulator.
It appears that is possible if event related to msg2 reception is scheduled before the one related to msg1

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);

RedPark Serial Cable partial data

I have an RFID scanner attached to a RedPark serial cable connected to an iPad app. When people scan their RFID cards, I get a callback with -readBytesAvailable:. However, sometimes it doesn't give me the entire RFID in one call. Sometimes it send it in two calls.
How can I determine if I've received everything? When my code takes the first callback's data and tries to use it, I get an error, because let's say the RFID was "123456789" sometimes I'll get one call with #"12" and a second call with #"3456789". So I try to process #"12" and get a user not found error, then I try to process #"3456789" and get a user not found error.
How can I tell if I'm done reading data? The lengths of the RFIDs can vary from vendor to vendor, so I can't just assume I need to read a certain number of digits.
This is the method I use to receive the data from the scanner through the RedPark:
- (void) readBytesAvailable:(UInt32)length {
NSLog(#"readBytesAvailable: %lu", length);
UInt8 rxLoopBuff[LOOPBACK_TEST_LEN];
[self.rfidManager read:rxLoopBuff Length:length];
NSString *rfid = [[NSString alloc] initWithBytes:rxLoopBuff length:length encoding:NSUTF8StringEncoding];
NSLog(#"rfid=%#", rfid);
[self receivedScanOfRFID:rfid];
}
Serial port gives you no control over packetization. Data is just a stream of bytes with no way to predict which bytes appear in each read call. You have to parse the data stream itself to interpret the contents and understand start/end of your messages. You either need to look for a reliable terminating character or potentially use a timeout approach where you do multiple reads until you get no more data for some period of time. I don't recommend the timeout approach.

Resources