How to bind to a broadcast address in Micrium - micrium

I'm trying to find a way to bind an IPv4 UDP socket to a broadcast address in Micrium (µC/OS-Ⅲ).
Attempt to bind a socket to the actual broadcast address just returns NET_SOCK_ERR_INVALID_ADDR. The broadcast is not explicitly mentioned on the list of things to bind on the NetSock_Bind call documentation, there is no analogue of SO_BROADCAST either. Is it impossible at all?
Can I, as a last resort, add a broadcast address to an existing interface as its own address (this shouldn't mess up ARP, since nobody is going to ask for it, and I'm not going to send anything through it)?

look at micrium documentation.
Follow the steps and you'll get no error.
BTW, if you won't use NetApp_SetSockAddrand try to bind using NetSock_Bind, you'll receive the NET_SOCK_ERR_INVALID_ADDR which happened to you.
Edit:
look at the next code, which works for me.
Note that the IP Address I manually initialized the host's address and used the defined address NET_SOCK_ADDR_IP_V4_WILDCARD.
NET_SOCK_ADDR_IPv4 host;
NET_ERR perr;
Mem_Clr(&host, sizeof(host));
host.AddrFamily = NET_SOCK_ADDR_FAMILY_IP_V4;
host.Addr = NET_UTIL_HOST_TO_NET_32(NET_SOCK_ADDR_IP_V4_WILDCARD);
host.Port = NET_UTIL_HOST_TO_NET_16(socketPort);
netSockId = NetSock_Open( NET_SOCK_PROTOCOL_FAMILY_IP_V4,
NET_SOCK_TYPE_DATAGRAM,
NET_SOCK_PROTOCOL_UDP,
&perr);
if (perr != NET_SOCK_ERR_NONE)
{
// log the error.
return;
}
NetSock_Bind( netSockId,
(NET_SOCK_ADDR*)&host,
NET_SOCK_ADDR_SIZE,
&perr);
if (perr != NET_SOCK_ERR_NONE)
{
// log the error.
return;
}
What I said about the NetApp_SetSockAddr() function, is that if I call it instead of manually initializing the host, it returned the error you received.

Related

How can I to transmit at least a "couple of bytes" on the local network (UEFI DXE)

I need to write driver (DXE), that can transmit "couple of bytes" from virtual machine (QEMU) to the host system (OS - Ubuntu). I've read the UEFI_Spec and Guide for developers, but I still don't understand, how to write the code and what protocol should I use (tried to use TCPv4 but can't even LocateHandleBuffer).
EFI_STATUS Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiTcp4ProtocolGuid, NULL, &HandleCount, &HandleBuffer);
I get:
EFI_UNSUPPORTED
If somebody can explain me or can show examples of the code, I'll be very grateful. Thanks.
For most network related protocols you first have to use the corresponding "Service Binding Protocol" to get a handle which contains the protocol you are looking for.
Use this steps to access the Tcp4Protocol:
gBS->LocateHandleBuffer(ByProtovol,gEfiTcp4ServiceBindingProtocolGuid, NULL, &HandleCount, &HandleBuffer);
// Loop over the HandleBuffer Array and pick the one you need
gBS->HandleProtocol(HandleBuffer[YourIndex], &gEfiTcp4ServiceBindingProtocolGuid, &Tcp4SBProtocol);
Tcp4SBProtocol->CreateChild(Tcp4SBProtocol, &Tcp4Handle);
gBS->HandleProtocol(Tcp4Handle, &gEfiTcp4ProtocolGuid, &Tcp4Protocol);
To check if a NIC is available you can use:
// This should return EFI_SUCCESS
gBS->LocateProtocol(&gEfiSimpleNetworkProtocolGuid, NULL, &SimpleNetworkProtocol);
There is a complete code sample for the HttpProtocol inside the Uefi specification (starting at page 1548), the Tcp4Protocol is not very different.

how to listen on L3 network layer?

I am creating a chat application backend and want to take into consideration the scalability.
I wanted to create a load balancer but not on the L7 layer where HTTP is located, but on the L3 layer where IP network is located to direct connections to the specific servers where I can then make TCP.
Is net.ListenIP the correct function to use to listen to the packets on the IP layer?
Is it the same as the higher Listen("tcp") for example? Is it the right method that I need to implement the load balancer?
Is there a reference to how the packet is structured so I am able get out from it the source and destination IPs to forward them?
If not tell me which function to use to listen on the L3 network layer to balance the loads to other servers.
Personally, I use gopacket in order to capture multiple network layers, and this library is very impressive.
When you're using gopacket, you are able to capture multiple network layers by specifying them, for example Ipv4, TCP, Ethernet...
For more information, see layers packet.
Then, you will be able to analyze your layers by using packet.Data(), which is a set of bytes that make up this entire packet, and then switch on the packet type to perform some actions.
For example, capturing multiple network layers on eth0 :
package main
import (
"fmt"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"time"
)
//Layers we want to decode
var (
ip4 layers.IPv4
eth layers.Ethernet
tcp layers.TCP
)
func main() {
//Array to store decoded layers
decodedLayers := []gopacket.LayerType{}
//Create parser
parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, &eth, &ip4, &tcp)
//Here we use pcap to capture packet on eth0 interface, we can also use afpacket for example, which is more efficient
handle, err := pcap.OpenLive("eth0", 65536, true, pcap.BlockForever)
if err != nil {
panic("Error opening pcap: " + err.Error())
}
datasource := gopacket.NewPacketSource(handle, layers.LayerTypeEthernet)
//packets will be a channel of packets
packets := datasource.Packets()
for {
select {
case packet := <-packets:
//We are decoding layers, and switching on the layer type
err := parser.DecodeLayers(packet.Data(), &decodedLayers)
for _, typ := range decodedLayers {
switch typ {
case layers.LayerTypeIPv4:
fmt.Printf("Source ip = %s - Destination ip = %s \n", ip4.SrcIP.String(), ip4.DstIP.String())
case layers.LayerTypeTCP:
//Here, we can access tcp packet properties
fmt.Println("Capture tcp traffic")
}
//etc ....
}
if len(decodedLayers) == 0 {
fmt.Println("Packet truncated")
}
//If the DecodeLayers is unable to decode the next layer type
if err != nil {
//fmt.Printf("Layer not found : %s", err)
}
}
}
}
After reading the Docs, yes this function will help you receive IP Packets.
ListenIP acts like ListenPacket for IP networks.
ListenIP is similar to ListenPacket("tcp") but for IP packets.
As for the structure of IP packets, and working with them, the net package doesn't seem to have that.
There's another package gopacket which looks like it will be able to help you read and modify packets from any layer.
In gopacket there is a Packet type, which allows working with the network layer.
Packet.NetworkLayer().LayerContent() and Packet.NetworkLayer().LayerPayload() will each return byte[] which you can interpret by the expected structure of an IP packet.
Note: Now that I've written this whole thing I have to imagine somebody out there has written a nice overlay/wrapper to make this easier. This is just the result of me Googling for 10 minutes. Maybe somebody else will answer with a better tool/method

How can I call an "AT command" in Codesys for a GSM modem? Not standard send_sms, etc

I have a GSM modem and a PLC. The PLC sees a modem (I use a *.lib and functional block "openPort"), but I don't understand how send an "AT command" to the modem, for example, "ate0".
First, to increase your understanding of AT commands in general, read the V.250 specification. That will go a long way in making you an AT command expert.
Then for the actual implementation, I do not know Codesys, so the following is pseudo code of the structure you should have for handling AT commands:
the_modem = openPort();
...
// Start sending ATE0
writePort(the_modem, "ATE0\r");
do {
line = readLinePort(the_modem);
} while (! is_final_result_code(line))
// Sending of ATE0 command finished (successfully or not)
...
closePort(the_modem);
Whatever you do, never, never use delay, sleep or similar as a substitute for waiting for the final result code. You can look at the code for atinout for an example for the is_final_result_code function (you can also compare to isFinalResponseError and isFinalResponseSuccess in ST-Ericsson's U300 RIL, although note that CONNECT is not a final result code. It is an intermediate result code, so the name isFinalResponseSuccess is not 100% correct).

Serial port access in vxworks not working

I am in a need to send data thru serial port in vxworks. I am using the following code. But
it is not working.can anyone point out what went wrong?
int f;
if(f=open("/tyCo/1",O_RDWR,0)<0)
{
printf("Error opening serial port.");
return 1;
}
write(f,"hello",5);
after running this code, no data is comming thru serial port but instead it comes thru
terminal(Tornado shell). The system has two serial devices /tyCo/1 and /tyCo/0. I tried them both, but the problem persists.
Thanks in adavnce
Likhin.
Have you set the baud rate?
if (iocl(m_fd, FIOBAUDRATE, rate )) == ERROR )
{
//throw error
}
It is possible that you are using the wrong name for the device, and that Tornado Shell is set to your default device. From vxdev.com:
If a matching device name cannot be found, then the I/O function is directed
at a default device. You can set this default device to be any device in the
system, including no device at all, in which case failure to match a device
name returns an error. You can obtain the current default path by using
ioDefPathGet( ). You can set the default path by using ioDefPathSet( ).
The 3rd parameter of "open" command is, if I am not wrong, the mode. I do not really understand what it is needed for in vxworks, except for code comparability with UNIX. In short -try to give some value like 0644 or 0666. I think this will help.

Blackberry getting notified when the internet connection is available.

is there any way to know whether the net is connected or not in a blackbery device .I have the following code but it was waiting till the network timed out.
int rc = connection.getResponseCode();
if (rc != HttpConnection.HTTP_OK) {
throw new IOException("HTTP response code: " + rc);
}
Is there any other way.
The title of this question has a different meaning than the body of the question. Based on the title, you can be notified when the network starts by using the RadioStatusListener interface, which defines a networkStarted() function. You could then use the checks that coldice recommends to make sure that the current network supports data transfer.
RadioStatusListner JavaDocs
There are several API for getting network info:
RadioInfo.isDataServiceOperational();
CoverageInfo.isOutOfCoverage();
WLANInfo.getWLANState();

Resources