温控daemon(五)socket监控

这篇博客我们主要分析thermal-engine的socket监控,包括应用client的注册回调,以及client发送thermal消息都是通过socket。在thermal-engine启动分析的时候我们看到其创建了4个socket。

1. socket初始化

我们从main函数的thermal_server_init函数分析,这个函数其实流程很简单,对创建的4个socket,thermal-engine是server端,要bind listen,最后创建了一个thead进行各个socket的收发工作。这个thread的函数是

int thermal_server_init(void)
{
	...
#ifdef ANDROID
	sockfd_server_send = android_get_control_socket(
				THERMAL_SEND_SOCKET_NAME);
	if (sockfd_server_send > -1) {
		sockfd_server_recv = android_get_control_socket(
					THERMAL_RECV_SOCKET_NAME);
		if (sockfd_server_recv < 0)
			goto error;

		sockfd_server_recv_passive = android_get_control_socket(
					THERMAL_RECV_PASSIVE_SOCKET_NAME);
		if (sockfd_server_recv_passive < 0)
			goto error;
		sockfd_server_rule = android_get_control_socket(
					THERMAL_SEND_RULE_SOCKET_NAME);
		if (sockfd_server_rule < 0)
			goto error;
	}
#endif
	if (sockfd_server_send > -1)
		goto end_file_socket_create;
	sockfd_server_send = socket(AF_LOCAL, SOCK_STREAM, 0);
	...

	sockfd_server_recv = socket(AF_LOCAL, SOCK_STREAM, 0);
	...

	sockfd_server_recv_passive = socket(AF_LOCAL, SOCK_STREAM, 0);
	...

	sockfd_server_rule = socket(AF_LOCAL, SOCK_STREAM, 0);
	...

	memset(&server_addr_send, 0, sizeof(struct sockaddr_un));
	snprintf(server_addr_send.sun_path, UNIX_PATH_MAX, THERMAL_SEND_CLIENT_SOCKET);
	server_addr_send.sun_family = AF_LOCAL;

	memset(&server_addr_recv, 0, sizeof(struct sockaddr_un));
	snprintf(server_addr_recv.sun_path, UNIX_PATH_MAX, THERMAL_RECV_CLIENT_SOCKET);
	server_addr_recv.sun_family = AF_LOCAL;

	memset(&server_addr_recv_passive, 0, sizeof(struct sockaddr_un));
	snprintf(server_addr_recv_passive.sun_path, UNIX_PATH_MAX, THERMAL_RECV_PASSIVE_CLIENT_SOCKET);
	server_addr_recv_passive.sun_family = AF_LOCAL;

	memset(&server_addr_rule, 0, sizeof(struct sockaddr_un));
	snprintf(server_addr_rule.sun_path, UNIX_PATH_MAX, THERMAL_SEND_RULE_SOCKET);
	server_addr_rule.sun_family = AF_LOCAL;

	/* Delete existing socket file if necessary */
	unlink(server_addr_send.sun_path);
	unlink(server_addr_recv.sun_path);
	unlink(server_addr_recv_passive.sun_path);
	unlink(server_addr_rule.sun_path);

	rc = bind(sockfd_server_send,(struct sockaddr  const *)&server_addr_send, sizeof(struct sockaddr_un));
	...
	rc = bind(sockfd_server_recv,(struct sockaddr  const *)&server_addr_recv, sizeof(struct sockaddr_un));
	...

	rc = bind(sockfd_server_recv_passive,(struct sockaddr  const *)&server_addr_recv_passive, sizeof(struct sockaddr_un));
	if (rc != 0) {
		msg("Thermal-Server: Recv passive socket: bind error - %s", strerror(errno));
		goto error;
	}

	rc = bind(sockfd_server_rule,(struct sockaddr  const *)&server_addr_rule, sizeof(struct sockaddr_un));
	...

	/* Allow any client to connect to send socket.
	   Allow any client to connect to passive receive socket.
	   Only root group clients can connect recieve socket. */
	chmod(server_addr_send.sun_path, 0666);
	chmod(server_addr_recv.sun_path, 0660);
	chmod(server_addr_recv_passive.sun_path, 0666);
	chmod(server_addr_rule.sun_path, 0666);

end_file_socket_create:
	sockfd_server_log = socket(AF_LOCAL, SOCK_STREAM, 0);
	if (sockfd_server_log < 0)
		goto error;

	memset(&server_log, 0, sizeof(struct sockaddr_un));
	snprintf(server_log.sun_path, UNIX_PATH_MAX, " %s",
			UI_LOCALSOCKET_NAME);
	server_log.sun_family = AF_LOCAL;

	/* abstract namespace socket starts with NULL char */
	server_log.sun_path[0] = '\0';
	rc = bind(sockfd_server_log,
			(struct sockaddr  const *)&server_log,
			(int)(sizeof(sa_family_t) + 1
			+ strlen(UI_LOCALSOCKET_NAME)));
    ...
	rc = listen(sockfd_server_send, NUM_LISTEN_QUEUE);
	...

	rc = listen(sockfd_server_recv, NUM_LISTEN_QUEUE);
	...

	rc = listen(sockfd_server_recv_passive, NUM_LISTEN_QUEUE);
	...

	rc = listen(sockfd_server_log, NUM_LISTEN_QUEUE);
	...

	rc = listen(sockfd_server_rule, NUM_LISTEN_QUEUE);
	...

	rc = pthread_create(&listen_client_fd_thread, NULL, do_listen_client_fd, NULL);
	......

	ret = 0;
	return ret;
error:
	......
	return ret;
}

2. 各个socket监听

do_listen_client_fd函数,这里我们主要讲一下两个socket一个是sockfd_server_send这个主要是client用来注册回调,另一个是sockfd_server_recv时client给thermal-engine发送消息的。我们先分析这个函数,后面我们再从client端进行分析。

static void *do_listen_client_fd(void *data)
{
	int fd;
	uint8_t i;
	int nread;
	int result;
	socklen_t client_len;
	int client_fd = -1;
	struct sockaddr_un client_addr;
	fd_set t_readfds,testfds;

	FD_ZERO(&t_readfds);
	FD_SET(sockfd_server_send, &t_readfds);
	FD_SET(sockfd_server_recv, &t_readfds);
	FD_SET(sockfd_server_recv_passive, &t_readfds);
	FD_SET(sockfd_server_log, &t_readfds);
	FD_SET(sockfd_server_rule, &t_readfds);

	for (i = 0; i < NUM_LISTEN_QUEUE; i++) {
		thermal_send_fds[i] = -1;
	}

	while(server_socket_exit != 1) {
		testfds = t_readfds;
		result = select(FD_SETSIZE, &testfds, (fd_set *)0,//使用select
			       (fd_set *)0, (struct timeval *) 0);
		if (result < 1) {
			msg("Thermal-Server: %s select error", __func__);
			break;
		}

		for (fd = 0; fd < FD_SETSIZE; fd++) {
			if (FD_ISSET(fd,&testfds)) {
				if (fd == sockfd_server_send) {
					client_len = sizeof(struct sockaddr_un);
					client_fd = accept(sockfd_server_send,//client的fd
						          (struct sockaddr *)&client_addr,
						           &client_len);
					if (client_fd < 0)
						continue;
					FD_SET(client_fd, &t_readfds);//将client的fd放入select
					info("Thermal-Server: Adding thermal event listener on fd %d\n", client_fd);
					for (i = 0; i < NUM_LISTEN_QUEUE && thermal_send_fds[i] != -1; i++)
							continue;
						if (i < NUM_LISTEN_QUEUE)
							thermal_send_fds[i] = client_fd;//将client的fd放入thermal_send_fds数组中
					notify_client_on_register(client_fd);//client注册回调

				} else if (fd == sockfd_server_recv ||
					   fd == sockfd_server_recv_passive) {
					client_len = sizeof(struct sockaddr_un);
					client_fd = accept(fd,
						          (struct sockaddr *)&client_addr,
						           &client_len);
					if (client_fd < 0)
						continue;
					thermal_recv_data_from_client(client_fd, fd);//从client收消息
					close(client_fd);
				} else if (fd == sockfd_server_log || fd == sockfd_server_rule) {
					client_len = sizeof(struct sockaddr_un);
					client_fd = accept(fd,
						           (struct sockaddr *)&client_addr,
							 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值