#include #include #include #include #include #include #include #include #include #include "common.h" #include "sys.h" #include "cfg.h" #include #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); }