|
@@ -0,0 +1,471 @@
|
|
|
|
|
+#include <stdio.h>
|
|
|
|
|
+#include <stdlib.h>
|
|
|
|
|
+#include <string.h>
|
|
|
|
|
+#include <unistd.h>
|
|
|
|
|
+#include <sys/socket.h>
|
|
|
|
|
+#include <netinet/in.h>
|
|
|
|
|
+#include <arpa/inet.h>
|
|
|
|
|
+#include <signal.h>
|
|
|
|
|
+#include <errno.h>
|
|
|
|
|
+#include "common.h"
|
|
|
|
|
+#include "sys.h"
|
|
|
|
|
+#include "cfg.h"
|
|
|
|
|
+#include <errno.h>
|
|
|
|
|
+#include "broadcast.h"
|
|
|
|
|
+#include "thread.h"
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+typedef struct {
|
|
|
|
|
+ int broad_sock_fd;
|
|
|
|
|
+ int mul_sock_fd;
|
|
|
|
|
+ struct sockaddr_in broadcast_addr;
|
|
|
|
|
+ struct sockaddr_in bind_addr;
|
|
|
|
|
+ struct ip_mreq mreq;
|
|
|
|
|
+}broad_cast_t;
|
|
|
|
|
+
|
|
|
|
|
+static broad_cast_t broad_cast;
|
|
|
|
|
+
|
|
|
|
|
+extern GlobalDeviceManager __globalDeviceManage;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+#define BROADCAST_PORT 31002
|
|
|
|
|
+#define BROADCAST_INTERVAL 5
|
|
|
|
|
+#define MAX_MESSAGE_SIZE 1024
|
|
|
|
|
+#define MULTICAST_PORT 31001
|
|
|
|
|
+#define MULTICAST_GROUP "224.0.0.88"
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+static volatile int running = 1;
|
|
|
|
|
+void signal_handler(int sig) {
|
|
|
|
|
+ running = 0;
|
|
|
|
|
+ printf("\nShutting down...\n");
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+#define TYPE_MESSGE "{"\
|
|
|
|
|
+ "\"version\":\"%s\","\
|
|
|
|
|
+ "\"powerState\":\"on\","\
|
|
|
|
|
+ "\"hostname\":\"%s\","\
|
|
|
|
|
+ "\"product_id\":\"%s\","\
|
|
|
|
|
+ "\"device_name\":\"%s\","\
|
|
|
|
|
+ "\"https\":true,"\
|
|
|
|
|
+ "\"network\":[{"\
|
|
|
|
|
+ "\"hostIP\":\"%s\","\
|
|
|
|
|
+ "\"netmask\":\"%s\","\
|
|
|
|
|
+ "\"gateway\":\"%s\","\
|
|
|
|
|
+ "\"dns1\":\"%s\","\
|
|
|
|
|
+ "\"dns2\":\"%s\","\
|
|
|
|
|
+ "\"mode\":\"%s\","\
|
|
|
|
|
+ "\"autoDNS\":true,"\
|
|
|
|
|
+ "\"macAddress\":\"%s\""\
|
|
|
|
|
+ "}]"\
|
|
|
|
|
+ "}\r\n"
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+void * broard_thread(void *argc)
|
|
|
|
|
+{
|
|
|
|
|
+ NetworkInfo_t nw4;
|
|
|
|
|
+ int r4 = sys_get_net(&nw4, IP_V4);
|
|
|
|
|
+ thread_handle_t *h=(thread_handle_t*)argc;
|
|
|
|
|
+
|
|
|
|
|
+ char message[MAX_MESSAGE_SIZE] = {0};
|
|
|
|
|
+ GlobalDeviceManager *mgr = &__globalDeviceManage;
|
|
|
|
|
+
|
|
|
|
|
+ while(h->quit == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ int len = snprintf(message,sizeof(message),TYPE_MESSGE,
|
|
|
|
|
+ VERSION,
|
|
|
|
|
+ mgr->_globalDevInfo.product.name,
|
|
|
|
|
+ mgr->_globalDevInfo.product.pnumber,
|
|
|
|
|
+ mgr->_globalDevInfo.product.pname,
|
|
|
|
|
+ getLocalIpAddress("eth0"),
|
|
|
|
|
+ getLocalMask("eth0"),
|
|
|
|
|
+ getLocalGateway("eth0"),
|
|
|
|
|
+ nw4.dns1,
|
|
|
|
|
+ nw4.dns2,
|
|
|
|
|
+ nw4.mode == 0 ? "dhcp" : "static",
|
|
|
|
|
+ get_mac_address("eth0"));
|
|
|
|
|
+ ssize_t sent = sendto(broad_cast.broad_sock_fd, message, len, 0, (struct sockaddr *)&(broad_cast.broadcast_addr), sizeof(broad_cast.broadcast_addr));
|
|
|
|
|
+ if (sent < 0) {
|
|
|
|
|
+ fprintf(stderr, "sendto failed (errno %d: %s)\n", errno, strerror(errno));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ printf("Broadcast Discovery message sent (%zd bytes)\n", sent);
|
|
|
|
|
+ }
|
|
|
|
|
+ sleep(BROADCAST_INTERVAL);
|
|
|
|
|
+ }
|
|
|
|
|
+ pthread_exit(NULL);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+void* broard_mul_thread(void *argc)
|
|
|
|
|
+{
|
|
|
|
|
+ NetworkInfo_t nw4;
|
|
|
|
|
+ int r4 = sys_get_net(&nw4, IP_V4);
|
|
|
|
|
+ thread_handle_t *h=(thread_handle_t*)argc;
|
|
|
|
|
+ GlobalDeviceManager *mgr = &__globalDeviceManage;
|
|
|
|
|
+
|
|
|
|
|
+ char message[MAX_MESSAGE_SIZE] = {0};
|
|
|
|
|
+ char buffer[1024];
|
|
|
|
|
+ while(h->quit == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ struct sockaddr_in sender_addr;
|
|
|
|
|
+ socklen_t sender_len = sizeof(sender_addr);
|
|
|
|
|
+
|
|
|
|
|
+ ssize_t received = recvfrom(broad_cast.mul_sock_fd, buffer, sizeof(buffer) - 1, 0,
|
|
|
|
|
+ (struct sockaddr *)&sender_addr, &sender_len);
|
|
|
|
|
+
|
|
|
|
|
+ if (received > 0) {
|
|
|
|
|
+ buffer[received] = '\0';
|
|
|
|
|
+ printf("Received multicast request from %s:%d: %s\n", inet_ntoa(sender_addr.sin_addr), ntohs(sender_addr.sin_port), buffer);
|
|
|
|
|
+
|
|
|
|
|
+ // Check if it's a discovery request
|
|
|
|
|
+ if (strstr(buffer,"\"command\":\"discover\"") != NULL) {
|
|
|
|
|
+
|
|
|
|
|
+ printf("Discovery request received, sending multicast discovery message...\n");
|
|
|
|
|
+
|
|
|
|
|
+ int len = snprintf(message,sizeof(message),TYPE_MESSGE,
|
|
|
|
|
+ VERSION,
|
|
|
|
|
+ mgr->_globalDevInfo.product.name,
|
|
|
|
|
+ mgr->_globalDevInfo.product.pnumber,
|
|
|
|
|
+ mgr->_globalDevInfo.product.pname,
|
|
|
|
|
+ getLocalIpAddress("eth0"),
|
|
|
|
|
+ getLocalMask("eth0"),
|
|
|
|
|
+ getLocalGateway("eth0"),
|
|
|
|
|
+ nw4.dns1,
|
|
|
|
|
+ nw4.dns2,
|
|
|
|
|
+ nw4.mode == 0 ? "dhcp" : "static",
|
|
|
|
|
+ get_mac_address("eth0"));
|
|
|
|
|
+
|
|
|
|
|
+ ssize_t sent = sendto(broad_cast.mul_sock_fd, message, len, 0, (struct sockaddr *)&sender_addr, sizeof(sender_addr));
|
|
|
|
|
+ if (sent < 0) {
|
|
|
|
|
+ fprintf(stderr, "sendto failed (errno %d: %s)\n", errno, strerror(errno));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ printf("Multicast Discovery message sent to %s:%d (%zd bytes)\n", inet_ntoa(sender_addr.sin_addr), ntohs(sender_addr.sin_port), sent);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if (received < 0) {
|
|
|
|
|
+ if (errno != EAGAIN && errno != EWOULDBLOCK) {
|
|
|
|
|
+ fprintf(stderr, "recvfrom failed (errno %d: %s)\n", errno, strerror(errno));
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ pthread_exit(NULL);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+void broadcast_init(void)
|
|
|
|
|
+{
|
|
|
|
|
+ GlobalDeviceManager *mgr = &__globalDeviceManage;
|
|
|
|
|
+ NetworkInfo_t nw4;
|
|
|
|
|
+ int r4 = sys_get_net(&nw4, IP_V4);
|
|
|
|
|
+
|
|
|
|
|
+ if(mgr->_globalDevInfo.broadcast.broad_enable)
|
|
|
|
|
+ {
|
|
|
|
|
+ broad_cast.broad_sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
|
|
|
+ if(broad_cast.broad_sock_fd < 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ perror("socket");
|
|
|
|
|
+ goto faild;
|
|
|
|
|
+ }
|
|
|
|
|
+ int broadcast = 1;
|
|
|
|
|
+ if (setsockopt(broad_cast.broad_sock_fd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0) {
|
|
|
|
|
+ perror("setsockopt SO_BROADCAST");
|
|
|
|
|
+ goto faild1;
|
|
|
|
|
+ }
|
|
|
|
|
+ broad_cast.broadcast_addr.sin_family = AF_INET;
|
|
|
|
|
+ broad_cast.broadcast_addr.sin_port = htons(mgr->_globalDevInfo.broadcast.broadcast_port);
|
|
|
|
|
+ broad_cast.broadcast_addr.sin_addr.s_addr = inet_addr(mgr->_globalDevInfo.broadcast.boardcast_ip);
|
|
|
|
|
+ //create broard thread
|
|
|
|
|
+
|
|
|
|
|
+ thread_start(THREAD_ID_BROADCAST,broard_thread,NULL);
|
|
|
|
|
+
|
|
|
|
|
+ broad_cast.mul_sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
|
|
|
+ if( broad_cast.mul_sock_fd < 0)
|
|
|
|
|
+ goto failed_mul;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ int reuse = 1;
|
|
|
|
|
+ if (setsockopt(broad_cast.mul_sock_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) {
|
|
|
|
|
+ perror("setsockopt SO_REUSEADDR");
|
|
|
|
|
+ goto failed_mul_1;
|
|
|
|
|
+ }
|
|
|
|
|
+ //struct sockaddr_in bind_addr;
|
|
|
|
|
+ memset(&broad_cast.bind_addr, 0, sizeof(broad_cast.bind_addr));
|
|
|
|
|
+ broad_cast.bind_addr.sin_family = AF_INET;
|
|
|
|
|
+ broad_cast.bind_addr.sin_port = htons(mgr->_globalDevInfo.broadcast.mulcast_port);
|
|
|
|
|
+ broad_cast.bind_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
|
|
+
|
|
|
|
|
+ if (bind(broad_cast.mul_sock_fd, (struct sockaddr *)&(broad_cast.bind_addr), sizeof(broad_cast.bind_addr)) < 0) {
|
|
|
|
|
+ perror("bind");
|
|
|
|
|
+ goto failed_mul_1;
|
|
|
|
|
+ }
|
|
|
|
|
+ int ttl = 255;
|
|
|
|
|
+ if (setsockopt(broad_cast.mul_sock_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0) {
|
|
|
|
|
+ perror("setsockopt IP_MULTICAST_TTL");
|
|
|
|
|
+ goto failed_mul_1;
|
|
|
|
|
+ }
|
|
|
|
|
+ int loopback = 0;
|
|
|
|
|
+ if (setsockopt(broad_cast.mul_sock_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loopback, sizeof(loopback)) < 0) {
|
|
|
|
|
+ perror("setsockopt IP_MULTICAST_LOOP");
|
|
|
|
|
+ goto failed_mul_1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ //struct ip_mreq mreq;
|
|
|
|
|
+ broad_cast.mreq.imr_multiaddr.s_addr = inet_addr(mgr->_globalDevInfo.broadcast.mulcast_ip);
|
|
|
|
|
+ broad_cast.mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
|
|
|
|
+ if (setsockopt(broad_cast.mul_sock_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &broad_cast.mreq, sizeof(broad_cast.mreq)) < 0) {
|
|
|
|
|
+ perror("setsockopt IP_ADD_MEMBERSHIP");
|
|
|
|
|
+ /*
|
|
|
|
|
+ char buff[256] = {0};
|
|
|
|
|
+ sprintf(buff,"ip route add default via %s dev eth0",nw4.gateway);
|
|
|
|
|
+ system(buff);
|
|
|
|
|
+ sleep(1);
|
|
|
|
|
+ if (setsockopt(broad_cast.mul_sock_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &broad_cast.mreq, sizeof(broad_cast.mreq)) < 0) {
|
|
|
|
|
+ perror("setsockopt IP_ADD_MEMBERSHIP");
|
|
|
|
|
+ goto failed_mul_1;
|
|
|
|
|
+ }
|
|
|
|
|
+ */
|
|
|
|
|
+ goto failed_mul_1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ struct timeval timeout;
|
|
|
|
|
+ timeout.tv_sec = 1; // 1 second timeout
|
|
|
|
|
+ timeout.tv_usec = 0;
|
|
|
|
|
+ if (setsockopt(broad_cast.mul_sock_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) {
|
|
|
|
|
+ perror("setsockopt SO_RCVTIMEO");
|
|
|
|
|
+ goto failed_mul_1;
|
|
|
|
|
+ }
|
|
|
|
|
+ //create broard mul thread
|
|
|
|
|
+
|
|
|
|
|
+ thread_start(THREAD_ID_MULCAST,broard_mul_thread,NULL);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return;
|
|
|
|
|
+failed_mul_1:
|
|
|
|
|
+ close(broad_cast.mul_sock_fd);
|
|
|
|
|
+ broad_cast.mul_sock_fd = -1;
|
|
|
|
|
+failed_mul:
|
|
|
|
|
+ return;
|
|
|
|
|
+faild1:
|
|
|
|
|
+ close(broad_cast.broad_sock_fd);
|
|
|
|
|
+ broad_cast.broad_sock_fd = -1;
|
|
|
|
|
+faild:
|
|
|
|
|
+ return;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void broadcast_deinit(void)
|
|
|
|
|
+{
|
|
|
|
|
+ if(broad_cast.mul_sock_fd > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ close(broad_cast.mul_sock_fd);
|
|
|
|
|
+ thread_stop(THREAD_ID_MULCAST);
|
|
|
|
|
+ broad_cast.mul_sock_fd = -1;
|
|
|
|
|
+ }
|
|
|
|
|
+ if(broad_cast.broad_sock_fd > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ close(broad_cast.broad_sock_fd);
|
|
|
|
|
+ thread_stop(THREAD_ID_BROADCAST);
|
|
|
|
|
+ broad_cast.broad_sock_fd = -1;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+void* broardcast_tread(void* args)
|
|
|
|
|
+{
|
|
|
|
|
+
|
|
|
|
|
+ int port = BROADCAST_PORT;
|
|
|
|
|
+ char message[MAX_MESSAGE_SIZE] ={0};
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ // signal(SIGINT, signal_handler);
|
|
|
|
|
+ // signal(SIGTERM, signal_handler);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
|
|
|
+ if (sockfd < 0) {
|
|
|
|
|
+ perror("socket");
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ int broadcast = 1;
|
|
|
|
|
+ if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0) {
|
|
|
|
|
+ perror("setsockopt SO_BROADCAST");
|
|
|
|
|
+ close(sockfd);
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ struct sockaddr_in broadcast_addr = {0};
|
|
|
|
|
+ broadcast_addr.sin_family = AF_INET;
|
|
|
|
|
+ broadcast_addr.sin_port = htons(port);
|
|
|
|
|
+ broadcast_addr.sin_addr.s_addr = inet_addr("192.168.1.147");
|
|
|
|
|
+
|
|
|
|
|
+ // char ip[32]={0};
|
|
|
|
|
+ // char mac[32] = {0};
|
|
|
|
|
+ // char mask[32] = {0};
|
|
|
|
|
+ // char gateway[32] = {0};
|
|
|
|
|
+ NetworkInfo_t nw4;
|
|
|
|
|
+ int r4 = sys_get_net(&nw4, IP_V4);
|
|
|
|
|
+ //paras_data_t* para = paras_get();
|
|
|
|
|
+
|
|
|
|
|
+ while (running) {
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ int len = snprintf(message,sizeof(message),TYPE_MESSGE,VERSION,"SmartPDU","1","",
|
|
|
|
|
+ getLocalIpAddress("eth0"),
|
|
|
|
|
+ getLocalMask("eth0"),
|
|
|
|
|
+ getLocalGateway("eth0"),
|
|
|
|
|
+ nw4.dns1,
|
|
|
|
|
+ nw4.dns2,
|
|
|
|
|
+ nw4.mode == 0 ? "dhcp" : "static",
|
|
|
|
|
+ get_mac_address("eth0"));
|
|
|
|
|
+ ssize_t sent = sendto(sockfd, message, len, 0, (struct sockaddr *)&broadcast_addr, sizeof(broadcast_addr));
|
|
|
|
|
+ if (sent < 0) {
|
|
|
|
|
+ fprintf(stderr, "sendto failed (errno %d: %s)\n", errno, strerror(errno));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ printf("Broadcast Discovery message sent (%zd bytes)\n", sent);
|
|
|
|
|
+ }
|
|
|
|
|
+ sleep(BROADCAST_INTERVAL);
|
|
|
|
|
+ }
|
|
|
|
|
+ close(sockfd);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ pthread_exit(NULL);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+void* multcast_tread(void* args)
|
|
|
|
|
+{
|
|
|
|
|
+ int port = MULTICAST_PORT;
|
|
|
|
|
+ char message[MAX_MESSAGE_SIZE] = {0};
|
|
|
|
|
+ // signal(SIGINT, signal_handler);
|
|
|
|
|
+ // signal(SIGTERM, signal_handler);
|
|
|
|
|
+
|
|
|
|
|
+ int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
|
|
|
+ if (sockfd < 0) {
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ int reuse = 1;
|
|
|
|
|
+ if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) {
|
|
|
|
|
+ perror("setsockopt SO_REUSEADDR");
|
|
|
|
|
+ close(sockfd);
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ struct sockaddr_in bind_addr;
|
|
|
|
|
+ memset(&bind_addr, 0, sizeof(bind_addr));
|
|
|
|
|
+ bind_addr.sin_family = AF_INET;
|
|
|
|
|
+ bind_addr.sin_port = htons(port);
|
|
|
|
|
+ bind_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
|
|
+
|
|
|
|
|
+ if (bind(sockfd, (struct sockaddr *)&bind_addr, sizeof(bind_addr)) < 0) {
|
|
|
|
|
+ perror("bind");
|
|
|
|
|
+ close(sockfd);
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ int ttl = 255;
|
|
|
|
|
+ if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0) {
|
|
|
|
|
+ perror("setsockopt IP_MULTICAST_TTL");
|
|
|
|
|
+ close(sockfd);
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+ int loopback = 0;
|
|
|
|
|
+ if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, &loopback, sizeof(loopback)) < 0) {
|
|
|
|
|
+ perror("setsockopt IP_MULTICAST_LOOP");
|
|
|
|
|
+ close(sockfd);
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ struct ip_mreq mreq;
|
|
|
|
|
+ mreq.imr_multiaddr.s_addr = inet_addr(MULTICAST_GROUP);
|
|
|
|
|
+ mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
|
|
|
|
+ if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
|
|
|
|
|
+ perror("setsockopt IP_ADD_MEMBERSHIP");
|
|
|
|
|
+ close(sockfd);
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ struct timeval timeout;
|
|
|
|
|
+ timeout.tv_sec = 1; // 1 second timeout
|
|
|
|
|
+ timeout.tv_usec = 0;
|
|
|
|
|
+ if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) {
|
|
|
|
|
+ perror("setsockopt SO_RCVTIMEO");
|
|
|
|
|
+ close(sockfd);
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Set up multicast send address
|
|
|
|
|
+ // struct sockaddr_in multicast_addr;
|
|
|
|
|
+ // memset(&multicast_addr, 0, sizeof(multicast_addr));
|
|
|
|
|
+ // multicast_addr.sin_family = AF_INET;
|
|
|
|
|
+ // multicast_addr.sin_port = htons(port);
|
|
|
|
|
+ // multicast_addr.sin_addr.s_addr = inet_addr(MULTICAST_GROUP);
|
|
|
|
|
+
|
|
|
|
|
+ char buffer[1024];
|
|
|
|
|
+ NetworkInfo_t nw4;
|
|
|
|
|
+ int r4 = sys_get_net(&nw4, IP_V4);
|
|
|
|
|
+
|
|
|
|
|
+ while (running) {
|
|
|
|
|
+ struct sockaddr_in sender_addr;
|
|
|
|
|
+ socklen_t sender_len = sizeof(sender_addr);
|
|
|
|
|
+
|
|
|
|
|
+ ssize_t received = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0,
|
|
|
|
|
+ (struct sockaddr *)&sender_addr, &sender_len);
|
|
|
|
|
+
|
|
|
|
|
+ if (received > 0) {
|
|
|
|
|
+ buffer[received] = '\0';
|
|
|
|
|
+ printf("Received multicast request from %s:%d: %s\n", inet_ntoa(sender_addr.sin_addr), ntohs(sender_addr.sin_port), buffer);
|
|
|
|
|
+
|
|
|
|
|
+ // Check if it's a discovery request
|
|
|
|
|
+ if (strstr(buffer, "\"command\":\"discover\"") != NULL) {
|
|
|
|
|
+
|
|
|
|
|
+ printf("Discovery request received, sending multicast discovery message...\n");
|
|
|
|
|
+
|
|
|
|
|
+ int len = snprintf(message,sizeof(message),TYPE_MESSGE,VERSION,"SmartPDU","1","",
|
|
|
|
|
+ getLocalIpAddress("eth0"),
|
|
|
|
|
+ getLocalMask("eth0"),
|
|
|
|
|
+ getLocalGateway("eth0"),
|
|
|
|
|
+ nw4.dns1,
|
|
|
|
|
+ nw4.dns2,
|
|
|
|
|
+ nw4.mode == 0 ? "dhcp" : "static",
|
|
|
|
|
+ get_mac_address("eth0"));
|
|
|
|
|
+
|
|
|
|
|
+ ssize_t sent = sendto(sockfd, message, len, 0, (struct sockaddr *)&sender_addr, sizeof(sender_addr));
|
|
|
|
|
+ if (sent < 0) {
|
|
|
|
|
+ fprintf(stderr, "sendto failed (errno %d: %s)\n", errno, strerror(errno));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ printf("Multicast Discovery message sent to %s:%d (%zd bytes)\n", inet_ntoa(sender_addr.sin_addr), ntohs(sender_addr.sin_port), sent);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if (received < 0 && running) {
|
|
|
|
|
+ if (errno != EAGAIN && errno != EWOULDBLOCK) {
|
|
|
|
|
+ fprintf(stderr, "recvfrom failed (errno %d: %s)\n", errno, strerror(errno));
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ close(sockfd);
|
|
|
|
|
+ pthread_exit(NULL);
|
|
|
|
|
+
|
|
|
|
|
+}
|