blob: 2ebf85f6fd66066e8db743276d1f5876b9604b20 [file] [log] [blame]
you.chen2f5cd7b2023-03-20 19:06:08 +08001#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
16static int lynq_urc_socket_fd = 0;
17static int registered_urc_socket_port = 0;
18static int registered_urc_socket_fd = 0;
19
20static pthread_mutex_t s_urc_broadcast_mtx = PTHREAD_MUTEX_INITIALIZER;
21static std::list<struct sockaddr*> s_urc_broadcast_clients;
22
23static 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
32static void * receive_client_heartbeat(void *parm);
33static void find_all_client_to_notify_online();
34int 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
65open_socket_exit:
66 pthread_mutex_unlock(&s_urc_broadcast_mtx);
67 return ret == 0 ? lynq_urc_socket_fd: -1;
68}
69
70int 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
92int 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, &registered_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);
130register_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
136int 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, &registered_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
173static 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}
209static 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
228static 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
247static 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}