I am trying to broadcast data but the output is udp send failed. I chose a random port 33333. What's wrong with my code?
int main()
{
struct sockaddr_in udpaddr = { sin_family : AF_INET };
int xudpsock_fd,sock,len = 0,ret = 0,optVal = 0;
char buffer[255];
char szSocket[64];
memset(buffer,0x00,sizeof(buffer));
memset(&udpaddr,0,sizeof(udpaddr));
udpaddr.sin_addr.s_addr = INADDR_BROADCAST;
udpaddr.sin_port = htons(33333);
xudpsock_fd = socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
optVal = 1;
ret = setsockopt(xudpsock_fd,SOL_SOCKET,SO_BROADCAST,(char*)&optVal,sizeof(optVal));
strcpy(buffer,"this is a test msg");
len = sizeof(buffer);
ret = sendto(xudpsock_fd,buffer,len,0,(struct sockaddr*)&udpaddr,sizeof(udpaddr));
if (ret == -1)
printf("udp send failed\n");
else
printf("udp send succeed\n");
return (0);
}
One problem is that the address family you are trying to send to is zero (AF_UNSPEC). Although you initialize the family to AF_INET at the top of the function, you later zero it out with memset.
On the system I tested with, the send actually works anyway for some strange reason despite the invalid address family, but you should definitely try fixing that first.
You probably had a problem with your default route (eg, you didn't have one). sendto needs to pick an interface to send the packet on, but the destination address was probably outside the Destination/Genmask for each defined interface (see the 'route' command-line tool).
The default route catches this type of packet and sends it through an interface despite this mismatch.
Setting the destination to 127.255.255.255 will usually cause the packet to be sent through the loopback interface (127.0.0.1), meaning it will be able to be read by applications that (in this case) are run on the local machine.
Related
I am trying to communicate with GSM module via UART communication. I could get message from the module as I expected. However when it comes to while loop (it is empty), debug session ends with "can not access target" error. Stepo by step, I am going to share my code:
Function 1 is AT_Send. (Note: Some of variables are declared globally.)
int AT_Send(UART_HandleTypeDef *huart, ATHandleTypedef *hat, unsigned char *sendBuffer, uint8_t ssize, unsigned char *responseBuffer, uint8_t rsize) {
if (HAL_UART_Transmit_IT(huart,sendBuffer,ssize) != HAL_OK) {
return -1;
}
while ((HAL_UART_GetState(huart) & HAL_UART_STATE_BUSY_TX) == HAL_UART_STATE_BUSY_TX) {
continue;
}
//;HAL_Delay(1000);
if (strstr((char*)receiveBuffer,(char*)responseBuffer) != NULL) {
rxIndex = 0;
memset(command, 0, sizeof(command));
return 0;
}
rxIndex = 0;
memset(command, 0, sizeof(command));
return 1;
}
Second function is AT_Init function. It sends AT to get OK response. At this point on, if I am not wrong, I am opening receive interrrupt and I am trying to get 1 byte.
int AT_Init(UART_HandleTypeDef *huart, ATHandleTypedef *hat)
{
HAL_UART_Receive_IT(huart,&rData,1);
tx = AT_Send(huart,hat,"AT\r",sizeof("AT\r\n"),"OK\r\n",sizeof("OK\r\n"));
return tx;
}
After these two functions, I am calling receive IT function in the call back while there are data on the bus.
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1){
command[rxIndex] = rData;
rxIndex++;
if((rxIndex == 2) && (strstr((char*)command,"\r\n") != NULL)) {
rxIndex = 0;
} else if (strstr((char*)command,"\r\n") != NULL) {
memcpy(receiveBuffer, command, sizeof(command));
rxIndex = 0;
memset(command,0,sizeof(command));
}
HAL_UART_Receive_IT(&huart1,&rData,1);
}
}
Moreover, I am going to send a few HTTP commands simultaneously if I can get rid of this problem.
Can anyone share his/her knowledge?
Edit: Main function is shown below
tx = AT_Init(&huart1,&hat);
while (1)
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_3);
HAL_Delay(500);
}
Edit 2: I had replaced uart channel by USART2, and debugger worked. I suppose that it is related to hardware. Still, I am curious about possible reasons that cause to this problem.
The question doesn't mention on which µC the program is running, I only see the "stm32" tag. Similarly, we don't know which debug protocol is used (JTAG or SWD?).
Still, I dare to guess that the toggle command for GPIO port PB3 in the main loop is causing the observations: On many (most? all?) STM32 controllers, PB3 is used as JTDO pin, which is needed for JTAG debug connections.
Please make sure to configure the debug connection to SWD (without SWO, i.e., neither SWV is correct). It may also help to check the wiring of the debug cable, the fast toggle at the PB3/JTDO line may influence the signal levels on some neighbouring SWD lines if the wiring is low quality or a fast SWD speed has been chosen.
My hypothesis can be falsified by removing all actions to PB3. If the problem remains, I'm wrong.
I was looking through a slide by IOvisor project, https://events.static.linuxfound.org/sites/events/files/slides/iovisor-lc-bof-2016.pdf
#include <bcc/proto.h>
struct IPKey { u32 dip; u32 sip; };
BPF_TABLE("hash", struct IPKey, int, mytable, 1024);
int recv_packet(struct __sk_buff *skb) {
struct IPKey key;
u8 *cursor = 0;
struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
key.dip = ip->dst;
key.sip = ip->src;
int *leaf = mytable.lookup(&key);
if (leaf)
*(leaf)++;
return 0;
}
This code is amongst the examples.
I've been using cursor_advance() quite often and now I'm trying to figure out what exactly it does.
I suspect that cursor is a pointer where we save the address of the packet we are parsing.
Then, with cursor_advance() we move the cursor by the size of the ethernet header, since ethernet_t contains all the ethernet header information.
Then, the cursor now at the address at the end of the ethernet header of the packet and if we use variables declared in the ethernet_t header, such as type, like : ethernet->type, we can access the information saved at type since the struct ethernet would read the values saved in that address?
I'm sorry my explanation is not really good.
I'm just looking for a general explanation or if my theory is correct.
Thanks!
Your understanding sounds correct to me. Just think of it as a “cursor” used to successively parse the different headers of your packet. The cursor_advance() macro is defined as:
#define cursor_advance(_cursor, _len) \
({ void *_tmp = _cursor; _cursor += _len; _tmp; })
It adds _len to the _cursor, and returns the value _cursor had before we added _len.
So the first call to cursor_advance() returns the initial value: ethernet points to the beginning of the packet, and we can use its attributes to access the different fields of the Ethernet header. But this same call also moves the cursor forwards by the length of the Ethernet header, so now it points to the beginning of the next header (L3, e.g. IP). The second call to cursor_advance() returns the pointer to the L3 layer, which we store in ip. The cursor is also moved forward and, assuming the packet is IPv4, would now point at the L4 header.
Note: I do not believe this mechanism is widely used in BPF programs aside from the few networking examples available in BCC. Instead, programs often navigate through packet headers with skb->data and skb->data_end.
I'm gonna to read/write under the modbus-tcp specification.
So, I'm trying to code the client and server in the linux environment.
(I would communicate with the windows program(as a client) using the modbus-tcp.)
but it doesn't work as I want, so I ask you here.
I'm testing the client code for linux as a client and the easymodbus as a server.
I used the libmodbus code.
I'd like to read coil(0x01) and write coil(0x05).
When the code is executed using the libmodbus, 'ff' is printed out from the Unit ID part.(according to the manual, 01 should be output for modbus-tcp.
I don't know why 'ff' is printed(photo attached).
Wrong result:
Expected result:
'[00] [00] .... [00]' ; Do you know where to control this part?
Do you have or do you know the sample code that implements the 'read/write' function using the libmodbus?
please let me know the information, if you know that.
ctx = modbus_new_tcp("192.168.0.99", 502);
modbus_set_debug(ctx, TRUE);
if (modbus_connect(ctx) == -1) {
fprintf(stderr, "Connection failed: %s\n",
modbus_strerror(errno));
modbus_free(ctx);
return -1;
}
tab_rq_bits = (uint8_t *) malloc(nb * sizeof(uint8_t));
memset(tab_rq_bits, 0, nb * sizeof(uint8_t));
tab_rp_bits = (uint8_t *) malloc(nb * sizeof(uint8_t));
memset(tab_rp_bits, 0, nb * sizeof(uint8_t));
nb_loop = nb_fail = 0;
/* WRITE BIT */
rc = modbus_write_bit(ctx, addr, tab_rq_bits[0]);
if (rc != 1) {
printf("ERROR modbus_write_bit (%d)\n", rc);
printf("Address = %d, value = %d\n", addr, tab_rq_bits[0]);
nb_fail++;
} else {
rc = modbus_read_bits(ctx, addr, 1, tab_rp_bits);
if (rc != 1 || tab_rq_bits[0] != tab_rp_bits[0]) {
printf("ERROR modbus_read_bits single (%d)\n", rc);
printf("address = %d\n", addr);
nb_fail++;
}
}
printf("Test: ");
if (nb_fail)
printf("%d FAILS\n", nb_fail);
else
printf("SUCCESS\n");
free(tab_rq_bits);
free(tab_rp_bits);
/* Close the connection */
modbus_close(ctx);
modbus_free(ctx);
return 0;
That FF you see right before the Modbus function is actually correct. Quoting the Modbus Implementation Guide, page 23:
On TCP/IP, the MODBUS server is addressed using its IP address; therefore, the
MODBUS Unit Identifier is useless. The value 0xFF has to be used.
So libmodbus is just sticking to the Modbus specification. I'm assuming, then, that the problem is in easymodbus, which is apparently expecting you to use 0x01as the unit id in your queries.
I imagine you don't want to mess with easymodbus, so you can fix this problem pretty easily from libmodbus: just change the default unit id:
modbus_set_slave(ctx, 1);
You could also go with:
rc = modbus_set_slave(ctx, MODBUS_BROADCAST_ADDRESS);
ASSERT_TRUE(rc != -1, "Invalid broadcast address");
to make your client address all slaves within the network, if you have more than one.
You have more info and a short explanation of where this problem is coming from in the libmodbus man page for modbus_set_slave function.
For a very comprehensive example, you can check libmodbus unit tests
And regarding your question number 5, I don't know how to answer it, the zeros you mean are supposed to be the states (true or false) you want to write (or read) to the coils. For writing you can change them with the value field of function modbus_write_bit(ctx, address, value).
I'm very grateful for your reply.
I tested the read/write function using the 'unit-test-server/client' code you recommended.
I've reviewed the code, but there are still many things I don't know.
However, there is an address value that acts after testing each other with unit-test-server/client code and there is an address value that does not work
(Do you know why?).
-Checked and found that the UT_BITS_ADDRESS (address value) value operates from 0x130 to 0x150
-'error Illegal data address' occurs at values below -0x130 and above 0x150
-The address I want to read/write is 0x0001 to 0x0004(Do you know how to do?).
I want to know how to process and transmit data like the TX part of the right picture.
enter image description here
I'm running both client and server in my Linux environment and I'm doing read/write testing.
Among the wrong pictures...[06][FF]... <-- I want to know how to modify FF part (to change the value to 01 as shown in the picture)
enter image description here
and "modbus_set_slave" is the function for modbus rtu?
I'd like to communicate PC Program and Linux device in the end.
so Which part do I use that function?
I thanks for your concern again.
I have been exploring on function select() to check if some sockets are ready to read and I must admit that I'm a bit confused. The MSDN says "The select function returns the total number of socket handles that are ready and contained in the fd_set structures".
Suppose I have 3 sockets and 2 sockets are ready, select() returns 2, but this gives me no information which 2 of these 3 sockets are ready to read so how can I check it?
On stack overflow I came across this: When select returns, it has updated the sets to show which file descriptors have become ready for read/write/exception
So I put breakpoints in my program to track my fd_set structure. What I have realized is that ( just one socket in fd_set): If socket is ready to read select():
returns 1
leaves fd_count (The number of sockets in the set) untouched
leaves fd_array (An array of sockets that are in the set.) untouched
If client did not send any data addressed to that socket select():
returns 0
decreases fd_count to 0
leaves fd_array untouched
If I call select() again and client again sent no data:
return -1 (I think this is because of the fd_count value - 0)
I guess I miss some crucial rules how select() works and what this function does but I can't figure out it.
Here is some code snippet to show what I do to call select():
CServer::CServer(char *ipAddress,short int portNumber)
{ // Creating socket
ServerSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (ServerSocket == INVALID_SOCKET)
std::cout << "I was not able to create ServerSocket\n";
else
std::cout << "ServerSocket created successfully\n";
// Initialization of ServerSocket Address
ServerSocketAddress.sin_family = AF_INET;
ServerSocketAddress.sin_addr.S_un.S_addr = inet_addr(ipAddress);
ServerSocketAddress.sin_port = htons(portNumber);
// Binding ServerSocket to ServerSocket Address
if (bind(ServerSocket, (SOCKADDR*)&ServerSocketAddress, sizeof(ServerSocketAddress)) == 0)
std::cout << "Binding ServersSocket and ServerSocketAddress ended with success\n";
else
std::cout << "There were problems with binding ServerSocket and ServerSocket Address\n";
// Initialization of the set of sockets
ServerSet.fd_count = 1;
ServerSet.fd_array[0] = ServerSocket;
}
In main :
CServer Server(IP_LOOPBACK_ADDRESS, 500);
tmp = select(0, &Server.ServerSet, NULL, NULL, &TimeOut);
Should't the fd_array be filled with 0 values after the select() call, when there is no socket that can be read?
You're suppose to use the FD_SET macro and friends. You're not doing that.
I'm working with a C++ project where two processes (running on the same machine) are communicating with each other via TCP, using WinSock. The process 'A' loads several Dll's which must be used by process 'B'.
However, I'm having trouble understanding how to use the send/recv methods in this case, for sending and receiving the HMODULE. Is it possible? and if so, what would be the correct way. (I've bee trying something as the following):
Process A:
HMODULE hmod = LoadLibrary(L"MathFunc.dll");
iResult = send( Socket, (char*)hmod, sizeof(HMODULE), 0 );
Process B:
typedef double (* addFunc)(double, double);
int __cdecl main(void)
{
...
HMODULE receiver;
iResult = recv(ClientSocket, (char*)&receiver, sizeof(HMODULE), 0);
addFunc adder = (addFunc)GetProcAddress(receiver, "Add");
double resi = adder(1.0, 2.0);
...
return 0;
}
Thanks.
The process 'A' loads several Dll's which must be used by process 'B'.
This is already impossible, let alone sending HMODULES around. A process must load its own DLLs.