I'm trying to figure out what I need to send (client) in the NTP request package to retrieve a NTP package from the server. I'm working with the LWIP on Cortex M3, Stellaris LM3S6965
I understand that I will recieve a UDP header and then the NTP protocol with the different timestamps the remove the latency. I probable need to make an UDP header but what do I need to add as data?
wireshark image:
I hope you guys can help me.
The client request packet is the same as the server reply packet - just set the MODE bits in the first word to 3 (Client) to be sure.
Send the whole 48 byte packet to the server, it will reply with the same.
The simplest packet would be 0x1B followed by 47 zeroes. (Version = 3, mode = 3)
This is for starters: http://www.eecis.udel.edu/~mills/ntp/html/warp.html
Check this out in case you haven't yet: https://www.rfc-editor.org/rfc/rfc5905
Then look at this: http://wiki.wireshark.org/NTP and check out the sample pcap files that they have uploaded.
I am not sure if this helped, but I hope so.
I have coded an Arduino to connect to an NTP server using this code here,
http://www.instructables.com/id/Arduino-Internet-Time-Client/step2/Code/
Look at the method called getTimeAndDate, and sendNTPpacket.
That is the packet that is sent. This is setting up a buffer and shows binary (0b) and hex (0x) being set up in the 48 character buffer. The address is the NTP time server,
memset(packetBuffer, 0, NTP_PACKET_SIZE);
packetBuffer[0] = 0b11100011;
packetBuffer[1] = 0;
packetBuffer[2] = 6;
packetBuffer[3] = 0xEC;
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
Udp.beginPacket(address, 123);
Udp.write(packetBuffer,NTP_PACKET_SIZE);
Udp.endPacket();
Here is what happens to the received packet,
Udp.read(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer
unsigned long highWord, lowWord, epoch;
highWord = word(packetBuffer[40], packetBuffer[41]);
lowWord = word(packetBuffer[42], packetBuffer[43]);
epoch = highWord << 16 | lowWord;
epoch = epoch - 2208988800 + timeZoneOffset;
flag=1;
setTime(epoch);
setTime is part of the arduino time library, so the epoch should be the number of seconds since Jan 1, 1900 as suggested here (search for epoch),
https://en.wikipedia.org/wiki/Network_Time_Protocol
But in case you want a C# version, I found this here, compiled the code under the excepted answer and it works. This will likely make more sense to you, and does show the use of epoch 1/1/1900.
How to Query an NTP Server using C#?
Can easily see the similarity.
Related
I made a setup which consists of 3 Zigbee's, 2 routers(Zigbee S2C's) and 1 coordinator(Zigbee S2). The routers are each connected to arduino nano which collects data from 2 FSR's and an IMU(frame type: zigbee transmit request and packet size 46 bytes) and sends it to the Coordinator attached to an arduino UNO. All the Xbees are in API mode 2 and working at a baud rate of 115200. I am using a library called "Simple Zigbee Library" to send all the collected data to the Coordinator. The collection and sending of data works fine except that there are packets lost in the way. The nano's sample data at a frequency of around 25Hz independently. The coordinator tries to read the data send from the zigbees(using the library of course) in every loop, but unfortunately, it seems to receive only around 40-45 samples.(Should have been 25*2=50 samples total from the 2 xbees). Can anybody suggest why this is happening. I need as less data loss as possible for my setup to achieve its motive. Any kind of help is appreciated.
P.S: It may be important to mention that the coordinator is reading the data only from one xbee in each loop.
As can be seen under the "Source" heading of this image of data received by the coordinator, "19" and "106" are the addresses of the routers and there are data packets dropped intermittently
Thank you.
void setup()
{
// Start the serial ports ...
Serial.begin( 115200 );
while( !Serial ){;} // Wait for serial port (for Leonardo only).
xbeeSerial.begin( 115200 );
// ... and set the serial port for the XBee radio.
xbee.setSerial( xbeeSerial );
// Set a non-zero frame id to receive Status packets.
xbee.setAcknowledgement(true);
}
void loop()
{
// While data is waiting in the XBee serial port ...
while( xbee.available() )
{
// ... read the data.
xbee.read();
// If a complete message is available, display the contents
if( xbee.isComplete() ){
Serial.print("\nIncoming Message: ");
printPacket( xbee.getIncomingPacketObject() );
}
}
delay(10); // Small delay for stability
// That's it! The coordinator is ready to go.
}
// Function for printing the complete contents of a packet //
void printPacket(SimpleZigBeePacket & p)
{
//Serial.print( START, HEX );
//Serial.print(' ');
//Serial.print( p.getLengthMSB(), HEX );
//Serial.print(' ');
//Serial.print( p.getLengthLSB(), HEX );
//Serial.print(' ');
// Frame Type and Frame ID are stored in Frame Data
uint8_t checksum = 0;
for( int i=10; i<p.getFrameLength(); i++){
Serial.print( p.getFrameData(i), HEX );
Serial.print(' ');
checksum += p.getFrameData(i);
}
// Calculate checksum based on summation of frame bytes
checksum = 0xff - checksum;
Serial.print(checksum, HEX );
Serial.println();
}
Although you claim to be using 115,200bps, posted code shows you opening the serial ports at 9600 baud, definitely not fast enough for 2500 bytes/second (50 packets/second * 45 bytes/packet * 110% for overhead) received from XBee and dumped by printPacket()). Remember that 802.15.4 is always 250kbps over the air, and the XBee module's serial port configuration is just for local communications with the host.
Make sure your routers are sending unicast (and not broadcast) packets to keep the radio traffic down.
You should verify that sending is working before troubleshooting code on the coordinator. Update the code on your routers to see if you get a successful Transmit Status packet for every packet sent. Aiming for 50Hz seems like a bit much -- you're trying to send 45 bytes (is that the full size of the API frame?) every 20ms.
Are you using a hardware serial port on the Arduino for both the XBee module and Serial.print()? How much time does each call to printPacket() take? If you reduce the code in printPacket() to a bare minimum (last byte of sender's address and the 1-byte frame ID), do you see all packets come through (an indication that you're spending too much time dumping the packets).
I'm concerned with the code you're using in loop. I don't know the deep internals of how the Arduino works, but does that 10ms delay block other code from processing data? What if you simplify it:
void loop()
{
xbee.read();
// Process any complete frames.
while (xbee.isComplete()){
Serial.print("\nIncoming Message: ");
printPacket( xbee.getIncomingPacketObject() );
}
}
But before going too far, you should isolate the problem would by connecting the coordinator to a terminal emulator on a PC to monitor the frame rate. If all frames arrive then there's an issue on the coordinator. If they don't, work on your router code first.
netty 4.0.24
I am passing XML over UDP. When receiving the UPD packet, the packet is always of length 2048, truncating the message. Even though, I have attempted to set the receive buffer size to something larger (4096, 8192, 65536) but it is not being honored.
I have verified the UDP sender using another UDP ingest mechanism. A standalone Java app using java.net.DatagramSocket. The XML is around 45k.
I was able to trace the stack to DatagramSocketImpl.createChannel (line 281). Stepping into DatagramChannelConfig, it has a receiveBufferSize of whatever I set (great), but a rcvBufAllocator of 2048.
Does the rcvBufAllocator override the receiveBufferSize (SO_RCVBUF)? Is the message coming in multiple buffers?
Any feedback or alternative solutions would be greatly appreciated.
I also should mention, I am using an ESB called vert.x which uses netty heavily. Since I was able to trace down to netty, I was hopeful that I could find help here.
The maximum size of incoming datagrams copied out of the socket is actually not a socket option, but rather a parameter of the socket read() function that your client passes in each time it wants to read a datagram. One advantage of this interface is that programs accepting datagrams of unknown/varying lengths can adaptively change the size of the memory allocated for incoming datagram copies such that they do not over-allocate memory while still getting the whole datagram. (In netty this allocation/prediction is done by implementors of io.netty.channel.RecvByteBufAllocator.)
In contrast, SO_RCVBUF is the size of a buffer that holds all of the datagrams your client hasn't read yet.
Here's an example of how to configure a UDP service with a fixed max incoming datagram size with netty 4.x using a Bootstrap:
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelOption;
import io.netty.channel.FixedRecvByteBufAllocator;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
int maxDatagramSize = 4092;
String bindAddr = "0.0.0.0";
int port = 1234;
SimpleChannelInboundHandler<DatagramPacket> handler = . . .;
InetSocketAddress address = new InetSocketAddress(bindAddr, port);
NioEventLoopGroup group = new NioEventLoopGroup();
Bootstrap b = new Bootstrap()
.group(group)
.channel(NioDatagramChannel.class)
.handler(handler);
b.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(maxDatagramSize));
b.bind(address).sync().channel().closeFuture().await();
You could also configure the allocator with ChannelConfig.setRecvByteBufAllocator
i would modify the content of Data in the UDP Packet read from a pcap file and send it on the network.
In the following example i write a string "User data" and it work correctly but if my data require more space than the previous payload opened, i get error, how i can increase dimension of payload data taken from the original pcap file?
Pcap pcap_off = Pcap.openOffline(fileName, errorBuf); //open original packet
PcapPacket temp= new PcapPacket(JMemory.Type.POINTER);
pcap_off.nextEx(temp); //only one UDp packet
JBuffer buff=new JBuffer(temp.size());
Ethernet eth=temp.getHeader(new Ethernet());
Ip4 ip=temp.getHeader(new Ip4());
Udp udp=temp.getHeader(new Udp());
Payload data=temp.getHeader(new Payload());
InetAddress dst = InetAddress.getByName("10.0.0.10");
ip.destination(dst.getAddress()); //modify ip dst
ip.checksum(ip.calculateChecksum());
eth.transferTo(buff);
ip.transferTo(buff, 0, ip.size(), eth.size());
*byte[] userdata = new String("User data").getBytes();*
*data.setByteArray(0,userdata);*
*data.transferTo(buff, 0, data.size(), eth.size() + ip.size()+ udp.size());*
int cs = udp.calculateChecksum(); //ricalcolo il checksum UDP
udp.setUShort(6, cs); //correct UDP checksum
udp.transferTo(buff, 0, udp.size(), eth.size() + ip.size());
JPacket new_packet =new JMemoryPacket(JProtocol.ETHERNET_ID,buff); //new packet
Many thanks to any answer.
You can't resize the buffer. You have to allocate a bigger buffer then the original packet so you have room to expand.
In your code, copy the packet from pcap buffer to jbuffer first, possibly one header at a time instead of the entire packet at once and make your changes as you go, one header at a time. The bigger buffer will give you room to include payload of any size.
For efficiency on windows systems you can also use the sendqueue which will allow you to compose many packets in a single large buffer.
I'm using a pcap.net process to broadcast out a packet, and listen in for a response. I want the response packets that it accepts to be a certain length. However, whenever I add a filter it only returns packets of length 100. Here's the code:
' Open the output device
Dim Communicator As PacketCommunicator = selectedOutputDevice.Open(100, PacketDeviceOpenAttributes.Promiscuous, 300)
Communicator.SetFilter("len >= 300")
' send broadcast packet
Communicator.SendPacket(BuildEthernetPacket(ReqInfoPkt, "ff:ff:ff:ff:ff:ff"))
' receive packets
While result = PacketCommunicatorReceiveResult.Ok And packetlist.Count < 500 And _
Not result = PacketCommunicatorReceiveResult.Timeout
result = Communicator.ReceivePacket(packet)
packetlist.Add(packet)
End While
Here's a link to the screen shot: link I tried asking on the pcap forums but didn't get a response.
So what am I doing wrong? Is there a synatx issue?
You open the device with the snapshot length set to 100 which means you cut all packets to be at most 100 bytes.
You should probably do
selectedOutputDevice.Open(65536, PacketDeviceOpenAttributes.Promiscuous, 300)
instead.
See the tutorial.
I'm building an embedded device with a couple of sensors. The device will 'stream' digital data from these sensors over Bluetooth or USB.
Most of the communication will be from the embedded device to the host. The host will infrequently be sending control messages, to control the gain etc.
Since the physical and data link layers are taken care of, I'm looking for a simple message protocol that will make it easy to develop user applications to process/display data on the host computer. Does anyone have any suggestions?
A simple text protocol may be the best for this application.
Use the communication channel as a bi-directional serial pipe.
The device can stream sensor values in ASCII (text) format, separated by commas, with each set separated by the newline character. The rate is preferably set by the host.
For example,
21204,32014 (new line character '\n' - 0x0A) at the end of each line
21203,32014
21202,32011
....
This makes it easier to test, to stream the values to a file, import in to a spreadsheet etc.
Similarly commands to the device too, is best done in text.
SET GAIN_1 2 ( sent by host )
OK ( reply by device )
SET GAIN_2 4 (sent by host )
OK ( reply by device )
SET GAIN_9 2 (sent by host )
ERROR ( reply by device if it does not understand)
SET RATE 500 ( set the sensor dump rate to every 500 ms )
OK