you.chen | 2f5cd7b | 2023-03-20 19:06:08 +0800 | [diff] [blame^] | 1 | #include <stdio.h>
|
| 2 | #include <stdlib.h>
|
| 3 | #include <string.h>
|
| 4 | //#include <binder/Parcel.h>
|
| 5 | #include <sys/socket.h>
|
| 6 | #include <netinet/in.h>
|
| 7 | #include <arpa/inet.h>
|
| 8 | #include <errno.h>
|
| 9 | #include <stdbool.h>
|
| 10 | #include <sys/types.h>
|
| 11 | #include <unistd.h>
|
| 12 | #include "lynq_urc_socket.h"
|
| 13 | #include "log/log.h"
|
| 14 | #include <list>
|
| 15 |
|
| 16 | static int lynq_urc_socket_fd = 0;
|
| 17 | static int registered_urc_socket_port = 0;
|
| 18 | static int registered_urc_socket_fd = 0;
|
| 19 |
|
| 20 | static pthread_mutex_t s_urc_broadcast_mtx = PTHREAD_MUTEX_INITIALIZER;
|
| 21 | static std::list<struct sockaddr*> s_urc_broadcast_clients;
|
| 22 |
|
| 23 | static pthread_mutex_t s_urc_register_mtx = PTHREAD_MUTEX_INITIALIZER;
|
| 24 |
|
| 25 | #define LYNQ_URC_SERVER_LISTEN_PORT 8086
|
| 26 | #define LYNQ_URC_SERVER_LISTEN_ADDRESS "127.0.0.1"
|
| 27 |
|
| 28 | #define LYNQ_URC_CLIENT_PORT_START 7050
|
| 29 | #define LYNQ_URC_CLIENT_PORT_END 7099
|
| 30 | #define LYNQ_URC_CLIENT_LISTEN_ADDRESS "127.0.0.1"
|
| 31 |
|
| 32 | static void * receive_client_heartbeat(void *parm);
|
| 33 | static void find_all_client_to_notify_online();
|
| 34 | int lynq_open_broadcast_urc_socket()
|
| 35 | {
|
| 36 | int ret = 0;
|
| 37 | int on = 1;
|
| 38 | pthread_mutex_lock(&s_urc_broadcast_mtx);
|
| 39 |
|
| 40 | struct sockaddr_in addr_serv;
|
| 41 | //Creating a Socket object
|
| 42 | lynq_urc_socket_fd=socket(AF_INET,SOCK_DGRAM,0);
|
| 43 | memset(&addr_serv, 0, sizeof(addr_serv));
|
| 44 | addr_serv.sin_family =AF_INET;
|
| 45 | addr_serv.sin_port = htons(LYNQ_URC_SERVER_LISTEN_PORT);
|
| 46 | addr_serv.sin_addr.s_addr = inet_addr(LYNQ_URC_SERVER_LISTEN_ADDRESS);
|
| 47 | ret = setsockopt(lynq_urc_socket_fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof on);
|
| 48 | if (ret < 0){
|
| 49 | goto open_socket_exit;
|
| 50 | }
|
| 51 | ret = bind(lynq_urc_socket_fd,(struct sockaddr*)&addr_serv,sizeof(addr_serv));
|
| 52 | if (ret < 0){
|
| 53 | goto open_socket_exit;
|
| 54 | }
|
| 55 | //receive registion and display on at port
|
| 56 | pthread_t thid;
|
| 57 | if(pthread_create(&thid, NULL, receive_client_heartbeat, NULL) != 0) {
|
| 58 | RLOGE("thread creation failed\n");
|
| 59 | ret = -1;
|
| 60 | goto open_socket_exit;
|
| 61 | }
|
| 62 |
|
| 63 | find_all_client_to_notify_online();
|
| 64 |
|
| 65 | open_socket_exit:
|
| 66 | pthread_mutex_unlock(&s_urc_broadcast_mtx);
|
| 67 | return ret == 0 ? lynq_urc_socket_fd: -1;
|
| 68 | }
|
| 69 |
|
| 70 | int lynq_broadcast_urc_msg(void * msg, int size)
|
| 71 | {
|
| 72 | int all_ok = 1;
|
| 73 | pthread_mutex_lock(&s_urc_broadcast_mtx);
|
| 74 | for(auto it=s_urc_broadcast_clients.begin(); it != s_urc_broadcast_clients.end(); )
|
| 75 | {
|
| 76 | int len = sendto(lynq_urc_socket_fd, msg, size, 0, *it, sizeof(struct sockaddr_in));
|
| 77 | if (len < 0)
|
| 78 | {
|
| 79 | struct sockaddr_in *addr_cli = (struct sockaddr_in *) *it;
|
| 80 | printf("remove client %d now\n", ntohs(addr_cli->sin_port));
|
| 81 | it = s_urc_broadcast_clients.erase(it);
|
| 82 | free(addr_cli);
|
| 83 | all_ok = 0;
|
| 84 | continue;
|
| 85 | }
|
| 86 | it++;
|
| 87 | }
|
| 88 | pthread_mutex_unlock(&s_urc_broadcast_mtx);
|
| 89 | return all_ok;
|
| 90 | }
|
| 91 |
|
| 92 | int lynq_register_urc_socket()
|
| 93 | {
|
| 94 | int on = 0;
|
| 95 | int ret = 0;
|
| 96 | int len_s;
|
| 97 | struct sockaddr_in addr_serv;
|
| 98 | //Creating a Socket object
|
| 99 | pthread_mutex_lock(&s_urc_register_mtx);
|
| 100 | registered_urc_socket_fd=socket(AF_INET,SOCK_DGRAM,0);
|
| 101 | memset(&addr_serv, 0, sizeof(addr_serv));
|
| 102 | addr_serv.sin_family =AF_INET;
|
| 103 | addr_serv.sin_addr.s_addr = inet_addr(LYNQ_URC_CLIENT_LISTEN_ADDRESS);
|
| 104 | if (registered_urc_socket_port > 0) {
|
| 105 | on = 1;
|
| 106 | ret = setsockopt(registered_urc_socket_fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof on);
|
| 107 | addr_serv.sin_port = htons(registered_urc_socket_port);
|
| 108 | ret = bind(registered_urc_socket_fd,(struct sockaddr*)&addr_serv,sizeof(addr_serv));
|
| 109 | if (ret < 0){
|
| 110 | goto register_socket_exit;
|
| 111 | }
|
| 112 | }
|
| 113 | else
|
| 114 | {
|
| 115 | for(registered_urc_socket_port = LYNQ_URC_CLIENT_PORT_START; registered_urc_socket_port < LYNQ_URC_CLIENT_PORT_END; registered_urc_socket_port ++)
|
| 116 | {
|
| 117 | addr_serv.sin_port = htons(registered_urc_socket_port);
|
| 118 | ret = bind(registered_urc_socket_fd,(struct sockaddr*)&addr_serv,sizeof(addr_serv));
|
| 119 | if (ret < 0){
|
| 120 | printf("bind socket %d fail\n", registered_urc_socket_port);
|
| 121 | continue;
|
| 122 | }
|
| 123 | break;
|
| 124 | }
|
| 125 | }
|
| 126 |
|
| 127 | addr_serv.sin_port = htons(LYNQ_URC_SERVER_LISTEN_PORT);
|
| 128 | len_s = sendto(registered_urc_socket_fd, ®istered_urc_socket_port, sizeof(registered_urc_socket_port), 0, (struct sockaddr *)&addr_serv,sizeof(addr_serv));
|
| 129 | printf("send result %d %d\n", len_s, errno);
|
| 130 | register_socket_exit:
|
| 131 | pthread_mutex_unlock(&s_urc_register_mtx);
|
| 132 | printf("init result %d\n", ret);
|
| 133 | return ret ==0 ? registered_urc_socket_fd : -1;
|
| 134 | }
|
| 135 |
|
| 136 | int lynq_recv_urc_msg(void * buffer, int size)
|
| 137 | {
|
| 138 | int ret = 0;
|
| 139 | struct sockaddr_in addr_serv;
|
| 140 | socklen_t len_addr_serv = sizeof(addr_serv);
|
| 141 | memset(&addr_serv, 0, sizeof(addr_serv));
|
| 142 | printf("client %ul to recv now\n", pthread_self());
|
| 143 | pthread_mutex_lock(&s_urc_register_mtx);
|
| 144 | if (registered_urc_socket_fd <= 0) {
|
| 145 | pthread_mutex_unlock(&s_urc_register_mtx);
|
| 146 | return -1;
|
| 147 | }
|
| 148 | while(1)
|
| 149 | {
|
| 150 | memset(buffer, 0, 4);
|
| 151 | ret = recvfrom(registered_urc_socket_fd, buffer, size,0,(struct sockaddr *)&addr_serv,(socklen_t*)&len_addr_serv);
|
| 152 | if (ret > 0 && LYNQ_URC_SERVER_LISTEN_PORT == ntohs(addr_serv.sin_port))
|
| 153 | {
|
| 154 | if (ret == 4 && LYNQ_URC_SERVER_LISTEN_PORT == *((int*)buffer))
|
| 155 | {
|
| 156 | sendto(registered_urc_socket_fd, ®istered_urc_socket_port, sizeof(registered_urc_socket_port), 0, (struct sockaddr *)&addr_serv,sizeof(addr_serv));
|
| 157 | printf("to send ack of headbeat\n");
|
| 158 | continue;
|
| 159 | }
|
| 160 | }
|
| 161 | else
|
| 162 | {
|
| 163 | printf("not a server packet\n");
|
| 164 | continue;
|
| 165 | }
|
| 166 | break;
|
| 167 | }
|
| 168 | pthread_mutex_unlock(&s_urc_register_mtx);
|
| 169 | printf("client %ul recv %d\n", pthread_self(), ret);
|
| 170 | return ret;
|
| 171 | }
|
| 172 |
|
| 173 | static void *receive_client_heartbeat(void *parm)
|
| 174 | {
|
| 175 | RLOGE("receive_at thread start\n");
|
| 176 | int recv = 0;
|
| 177 | char buffer[1024] = {0};
|
| 178 | while(1)
|
| 179 | {
|
| 180 | RLOGE("receive third at cmd\n");
|
| 181 |
|
| 182 | socklen_t len = sizeof(struct sockaddr_in);
|
| 183 | struct sockaddr* cli = (struct sockaddr*)malloc(len);
|
| 184 | bzero(cli, len);
|
| 185 | printf("to recv now\n");
|
| 186 | recv = recvfrom(lynq_urc_socket_fd, buffer, 1024, 0, cli, &len);
|
| 187 | if(recv < 0)
|
| 188 | {
|
| 189 | RLOGE("recv fail\n");
|
| 190 | printf("recv fail\n");
|
| 191 | free(cli);
|
| 192 | continue;
|
| 193 | }
|
| 194 | printf("recv a packet %d \n", recv);
|
| 195 | struct sockaddr_in * register_socket = (struct sockaddr_in*)cli;
|
| 196 |
|
| 197 | int port = ntohs(register_socket->sin_port);
|
| 198 | if (recv == 4 && port == *((int*)buffer))
|
| 199 | {
|
| 200 | printf("port is %d\n", port);
|
| 201 | pthread_mutex_lock(&s_urc_broadcast_mtx);
|
| 202 | s_urc_broadcast_clients.push_back(cli);
|
| 203 | pthread_mutex_unlock(&s_urc_broadcast_mtx);
|
| 204 | RLOGE("recvfrom from client\n");
|
| 205 | }
|
| 206 | }
|
| 207 | return NULL;
|
| 208 | }
|
| 209 | static int exec_cmd(const char *str_cmd, char * str_cmd_ret, size_t max_len)
|
| 210 | {
|
| 211 | FILE *fp;
|
| 212 | //printf("to exec cmd:%s\n", str_cmd);
|
| 213 | if((fp=popen(str_cmd,"r"))==NULL)
|
| 214 | {
|
| 215 | perror("popen error!");
|
| 216 | return -1;
|
| 217 | }
|
| 218 | if((fread(str_cmd_ret,max_len,1,fp))<0)
|
| 219 | {
|
| 220 | perror("fread fail!");
|
| 221 | fclose(fp);
|
| 222 | return -1;
|
| 223 | }
|
| 224 | fclose(fp);
|
| 225 | return 0;
|
| 226 | }
|
| 227 |
|
| 228 | static int lynq_split(char * str, int len, char delimiter, char * results[]) {
|
| 229 | int ret = 0;
|
| 230 | char * end = str + len - 1;
|
| 231 | results[ret++] = str;
|
| 232 | while(str < end) {
|
| 233 | if (*str == delimiter) {
|
| 234 | *str++ = '\0';
|
| 235 | results[ret++] = str;
|
| 236 | continue;
|
| 237 | }
|
| 238 | str++;
|
| 239 | }
|
| 240 | if (*str == delimiter) {
|
| 241 | *str = '\0';
|
| 242 | }
|
| 243 |
|
| 244 | return ret;
|
| 245 | }
|
| 246 |
|
| 247 | static void find_all_client_to_notify_online()
|
| 248 | {
|
| 249 | char buffer[1024] = {0};
|
| 250 | char * split_lines[128]= {0};
|
| 251 | int count = 0;
|
| 252 | int port, len;
|
| 253 | int local_port = LYNQ_URC_SERVER_LISTEN_PORT;
|
| 254 | printf("find_all_client_to_notify_online\n");
|
| 255 | if (exec_cmd("netstat -an | grep -e \"127\\.0\\.0\\.1:70[5-9][0-9]\" | awk '{print $4}' | awk -F \":\" '{print $2}'", buffer, 1024) == 0)
|
| 256 | {
|
| 257 | count = lynq_split(buffer, 1024, '\n', split_lines);
|
| 258 | for(int i=0; i < count;i++)
|
| 259 | {
|
| 260 | port = atoi(split_lines[i]);
|
| 261 | printf("got %s port:%d\n", split_lines[i], port);
|
| 262 | if (port < LYNQ_URC_CLIENT_PORT_START || port > LYNQ_URC_CLIENT_PORT_END)
|
| 263 | continue;
|
| 264 |
|
| 265 | struct sockaddr_in addr_serv;
|
| 266 | memset(&addr_serv, 0, sizeof(addr_serv));
|
| 267 | addr_serv.sin_family =AF_INET;
|
| 268 | addr_serv.sin_addr.s_addr = inet_addr(LYNQ_URC_CLIENT_LISTEN_ADDRESS);
|
| 269 | addr_serv.sin_port = htons(port);
|
| 270 | len = sendto(lynq_urc_socket_fd, &local_port, sizeof(local_port), 0, (struct sockaddr *)&addr_serv,sizeof(addr_serv));
|
| 271 | printf("send result %d %d\n", len, errno);
|
| 272 | }
|
| 273 | }
|
| 274 | else
|
| 275 | {
|
| 276 | printf("net stat fail\n");
|
| 277 | }
|
| 278 | }
|