I'm trying to send ethernet packet to choosed destination MAC address using jPcap:
public void sendPacket(Packet packet, byte[] srcMac, byte[] dstMac, Interface i) throws IOException
{
JpcapSender sender = JpcapSender.openDevice(i.netInterface);
EthernetPacket ether = new EthernetPacket();
ether.frametype = EthernetPacket.ETHERTYPE_IP;
ether.src_mac = srcMac; // MAC address of selected interface
ether.dst_mac = dstMac; // MAC addr. choosed somwhere on form
packet.datalink = ether;
sender.sendPacket(packet);
sender.close();
}
It works, but it's always sent to the selected interface not to the dst_mac!
So I don't understand the relation between selected interface and scr_mac:
why I have to choose both (interface and scr_mac)?
why I have to add dst_mac even if it's not used?
how to send packet out of my computer then?
why I have to choose both (interface and scr_mac)?
The interface is what the software is using to communicate (to send or receive packets). This is usually your ethernet card. You need to specify it so that Jpcap knows how to send the information. The src_mac address is part of the packet header. It is intended to be used dynamically so that as the packets are being sent they are updated with the appropriate information. The src_mac does not necessarily play a role in how the packet is sent.
why I have to add dst_mac even if it's not used?
It is used. Make sure that you have the other device with the specified mac address linked to your source by a direct ethernet connection, and also make sure that it is ready to receive the data. Right now, what I suspect is happening, is you're trying to read back through your same interface on the host computer.
Jpcap's website has some tutorials and samples I found useful. I've worked quite a bit with the Jpcap library, and I would be happy to help you if you have any more questions.
Related
I am using bacnet4j library to discover Remote BACnet devices. In the same network, everything is working as expected. But I could not find the BACnet controller device located in the different network.
String hostAddress="10.8.102.28";
IpNetwork network = new IpNetworkBuilder().withPort(47808).withSubnet(hostAddress, 24).build();
Transport transport = new DefaultTransport(network);
LocalDevice localDevice = new LocalDevice(Integer.decode(this.settings.getDeviceId()), transport);
localDevice.initialize();
//Finding remote device
int remoteId=1234;
RemoteDeviceFuture remoteFuture = RemoteDeviceFinder.findDevice(localDevice, remoteId);
RemoteDevice remoteDevice = null;
try {
remoteDevice = remoteFuture.get(); //remote device is null here
} catch (Exception e) {
LOGGER.error("Remote device with id " + remoteId + " does NOT exist!");
}
The above code snippet finds remote device with a given remoteId in the same network. But it can not find a device located in different network. Is there anything wrong here?
That is actually by design. The discovery process takes place using broadcast "Who-Is" messages that are not routed via IP routers. So any devices on a different IP subnet are not discovered this way. If you know the IP address of the remote device, you may be able to configure/program the IP directly as a static IP address.
However, there is something called a BBMD (BACnet Broadcast Management Device). One of these needs to be placed on each subnet, each configured with the IP address of the other BBMD. The BBMDs will intercept the BACnet related broadcasts on its subnet, send it across to the peer BBMD on the other subnet, which will retransmit the broadcast, effectively bridging the two (or more) subnets.
OR, your could configure/program your client as a "Foreign Device", have it register with a BBMD on the far subnet, which will achieve much the same.
BBMDs are fairly common. Most (all) BACnet/IP to BACnet MS/TP routers have the functionality. A lot of BACnet devices also allow the functionality to be enabled.
Hope this helps. See http://www.bacnetwiki.com for more.
UDP/IP Broadcasts - that are used as part of the 'Who-Is' (BACnet) service, generally are not routed by default and in most cases will not be allowed to be routed - e.g. security concerns been the main reason.
But if routing is in place, you could send unicast/directed traffic to the device in question.
(If I remember correctly, theoretically you should now be able to now send a Who-Is as a unicast/directed request - but even if I'm correct in saying that, it's highly likely that the majority of devices will only be listening for Who-Is services via broadcasts only.)
BBMD's are not strictly necessary - and have been considered as security concern as they can give out too much info.
It can be possible to use (effectively) bog-standard network routing instead of a BBMD - having traffic fly across a few different/target VLANs.
(Also be aware of mixing the use of a private IP(v4) address - of your choosing, and a public IP(v4) address - between the client & server/serving-device, you might encounter issues.)
The code is only streaming for one user at a time. Can anyone help me to play the stream in more than one system at the same time(convert it to multicast or broadcast).
Thanks in advance.
The library source is over here:
https://github.com/fyhertz/libstreaming
my current code is:
mSurfaceView = (net.majorkernelpanic.streaming.gl.SurfaceView) findViewById(R.id.surface);
// Sets the port of the RTSP server to 1234
Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit();
editor.putString(RtspServer.KEY_PORT, String.valueOf(5060)); // audio port num
editor.commit();
// Configures the SessionBuilde
SessionBuilder.getInstance()
.setSurfaceView(mSurfaceView)
.setPreviewOrientation(90)
.setContext(getApplicationContext())
.setAudioEncoder(SessionBuilder.AUDIO_AAC)
.setVideoEncoder(SessionBuilder.VIDEO_NONE);
MainActivity.this.startService(new Intent(MainActivity.this,RtspServer.class));
I looked at the code at github and seems that you only need to specify the multicast address to the SessionBuilder class and then the underlying RTSP server and RTP transport should handle everything (at least the RTSP responses seem have code to produce correct transport descriptions). So I guess adding a setDestination call to your SessionBuilder configuration should be ok (replace the 232.0.1.2 with the address you need):
// Configures the SessionBuilde
SessionBuilder.getInstance()
.setSurfaceView(mSurfaceView)
.setPreviewOrientation(90)
.setContext(getApplicationContext())
.setAudioEncoder(SessionBuilder.AUDIO_AAC)
.setVideoEncoder(SessionBuilder.VIDEO_NONE)
.setDestination("232.0.1.2");
The clients will still connect to the RTSP server through it's address but the actual RTP stream should be single and shared among all the clients.
I have a USB device that I'm attempting to communicate to with my Android 4.1 device using the MonoDroid API, and I've run into some issues setting up a proper connection. First, the steps taken to arrive at what I "think" may be an issue:
Filter my device by vendor and product ID with an intent filter in
my AndroidManifest file. This works well, as when I plug in my
device my app requests to launch by default, so permissions should
correct.
Grab my USB device from an Activity that my intent filter sends the program after discovering said device: UsbDevice device = (UsbDevice)this.Intent.GetParcelableExtra(UsbManager.ExtraDevice);
After checking that there is only one interface present, I grab the associated interface by issuing: UsbInterface intf = device.GetInterface(0);
Check the number of endpoints and grab them. There's 2, as this is an input and output device: UsbEndpoint endpoint_IN = intf.GetEndpoint(0);
UsbEndpoint endpoint_OUT = intf.GetEndpoint(1);
Grab a connection to the device using the UsbManager: UsbDeviceConnection connection = device_manager.OpenDevice(device);
However, and I noticed that the endpoint at index 0 of the interface (endpoint_IN above) has UsbAddressing enumeration type "DirMask", where endpoint_OUT has type "Out"; I'd expect endpoint_IN to be "In", which is not the case. What is "DirMask?" The inline documentation states "Documentation for this section has not yet been entered", and the online docs reflect the same: http://api.xamarin.com/?link=T%3aAndroid.Hardware.Usb.UsbAddressing
Could this be my issue? I'm just not really sure. I tried to implement the rest of the communication procedure, but haven't been able to yield any results. For example, the following code should input a command to receive one reading:
Byte[] sys_command = Encoding.ASCII.GetBytes("!001:SYS?\r");
Java.Nio.ByteBuffer sys_command_buffer = Java.Nio.ByteBuffer.Wrap(sys_command);
Java.Nio.ByteBuffer output_buffer = Java.Nio.ByteBuffer.Allocate(4);
UsbRequest request_out = new UsbRequest();
request_out.Initialize(connection, endpoint_OUT);
connection.ClaimInterface(intf, forceClaim);
request_out.Queue(output_buffer, 4);
connection.BulkTransfer(endpoint_IN, sys_command, sys_command.Length, TIMEOUT);
if (connection.RequestWait() == request_out)
readings.Text = output_buffer.GetFloat(0).ToString();
Any insight?
I had the interface endpoints backwards, all things considered. That is, I was attempting to read/write to the wrong interface.
In case anyone else stumbles on this, the DirMask type means look at the Direction attribute of the endpoint instead of the Type attribute. If the Type is DirMask, the Direction could be UsbAddressing.In or Out.
And the Direction of In is the out endpoint, and vice versa (which I'm guessing is why you had them backwards).
I am connected to a WLAN, where a special hardware device is connected to as well. I communicate to that device via a socket, since I know its IP.
Is there a was to identify that hardware device in the network by an id? I found out in Java it is not possible to obtain the MAC-address of a connected device. Is there any other alternative?
Thanks,
best regards
Mac addresses should be unique. Maybe you can get needed information from the ARP table.
Command "arp -a" works on Windows and Linux.
But there is a problems:
This is not portable way
The ARP table is quite variable
If the device is behind a router, then this does not work.
In Java you can call NetworkInterface.getHardwareAddress() that will return hardware MAC address
Enumeration<NetworkInterface> enumNicList = NetworkInterface.getNetworkInterfaces();
while(enumNicList.hasMoreElements())
{
NetworkInterface oNic = enumNicList.nextElement();
byte[] baMacAddress = oNic.getHardwareAddress();
String sMacAddress = new BigInteger(1, baMacAddress).toString(16);
System.out.println(sMacAddress);
}
If you don't have any control of the responses of the device, and the device doesn't contain any identifying API calls and such, then just use the IP address and make that IP statically assigned to that device via your router. Then you can either create your own table of IP <-> device list, or even scrape the IP table off your router.
Come to think of it, you could probably get the MAC address the same way - scrape the DHCP table off your router's configuration screen.
I am working on an application, using java, that has the following features:
User connects his mobile to a PC using a usb cable or bluetooth.
User types a message on his PC (in the textfield provided by my software).
User types a phone number (in a textbox provided by my software).
User clicks the send button.
Then, the software should send the message to the specified phone number and appropriate charges should be applied to my mobile balance. In other words, I am directing my mobile through my software to send message to a specified number.
How shall i do that? Is core java sufficient for this purpose or i have to use j2me or is there any particular java framework that would be suitable for this?
One option is to connect the phone to the pc using serial link (COM). Need to configure the phone connected physically by USB or Bluetooth in order to appear in a COM (serial) port.
Then you need to create an application for PC (Java or whatever can open serial ports) that opens the COM port used by the phone and send the proper AT commands. Serial port can be opened by JavaComm 2.0 Win32 or more recently RxTx.
Open the serial port and write and read command by writing and reading bytes, in the same way a socket.
Then create a visual application that let user set the information like phone number for destination, text...
You need Java SE or whatever language allows you to create visual applications and opening serial ports (Java, .NET, Python...).
Some links about AT commands by serial port in Windows: 1, 2, 3.
Another option could be using native API from the mobile OS through a socket, but seems complex and using AT commands and serial port should work for all phones and the only problem is connecting the phone by serial over USB or BlueTooth and managing the serial port.
This is highly dependent on the Mobile OS you're using. Are you using Windows Mobile, Android OS, BlackBerry OS?
If you're using Android, then you should use the built in SmsManager to do that. The SmsManager can do the following:
Manages SMS operations such as sending data, text, and pdu SMS messages.
Update:
Since you're using Symbian OS, then check out the documentation for more information on sending SMS messages. I assume that you can figure out the rest (i.e. how to get the text fields for the number and the message, etc.)
Here is an example from the Symbian OS documentation:
public boolean sendSms(String number, String message){
boolean result = true;
try {
//sets address to send message
String addr = "sms://"+number;
// opens connection
MessageConnection conn = (MessageConnection) Connector.open(addr);
// prepares text message
TextMessage msg =
(TextMessage)conn.newMessage(MessageConnection.TEXT_MESSAGE);
//set text
msg.setPayloadText(message);
// send message
conn.send(msg);
conn.close();
} catch (SecurityException se) {
// probably the user has not allowed to send sms
// you may want to handle this differently
result = false;
} catch (Exception e) {
result = false;
}
return result;
}
The above snippet came from the guide on "How to Send Text SMS in Java ME"