1 /*
2  * Copyright (C)2021-2022 Intel Corporation.
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 #ifndef _UART_CHANNEL_H_
6 #define _UART_CHANNEL_H_
7 #include <sys/queue.h>
8 #include <pthread.h>
9 #include <semaphore.h>
10 #include <sys/un.h>
11 #include "uart.h"
12 
13 #define WAIT_USER_VM_POWEROFF (10*SECOND_TO_US)
14 
15 #define CHANNEL_DEV_NAME_MAX 128U
16 #define CHANNEL_DEV_BUF_LEN 256U
17 
18 #define MIN_RESEND_TIME 3U
19 #define LISTEN_INTERVAL (5 * SECOND_TO_US)
20 
21 typedef void data_handler_f(const char *cmd_name, int fd);
22 
23 struct channel_dev {
24 	struct uart_dev *uart_device;
25 	char name[CHANNEL_DEV_NAME_MAX]; /**< channel device name */
26 	bool listening; /**< listen thread loop flag */
27 	bool polling; /**< message polling thread loop flag */
28 	pthread_t listen_thread;
29 	pthread_t pool_thread;
30 
31 	char buf[CHANNEL_DEV_BUF_LEN]; /**< store received message */
32 
33 	LIST_ENTRY(channel_dev) list; /**< list node used in UART connection list */
34 	LIST_ENTRY(channel_dev) open_list; /**< list node used UART opening list */
35 
36 	struct uart_channel *channel; /**< point to UART server */
37 	sem_t dev_sem; /**< semaphore used to start polling message */
38 	char resend_buf[CHANNEL_DEV_BUF_LEN]; /**< store the message that will be sent */
39 	unsigned int resend_time; /**< the time which the message will be resent */
40 };
41 struct channel_config {
42 	char identifier[CHANNEL_DEV_NAME_MAX]; /**< the user VM name which is configured by user */
43 };
44 struct uart_channel {
45 	data_handler_f *data_handler;
46 	LIST_HEAD(tty_head, channel_dev) tty_conn_head; /* UART connection list */
47 	LIST_HEAD(tty_open_head, channel_dev) tty_open_head; /* UART opening list */
48 	pthread_mutex_t tty_conn_list_lock;
49 
50 	struct channel_config conf;
51 };
52 /**
53  * @brief Initialize each field of uart channel instance, such as
54  * a lock and configuration of uart channel
55  */
56 struct uart_channel *init_uart_channel(char *id);
57 /**
58  * @brief Create one uart channel device according to device name
59  *
60  * Create one channel device instance to store information about
61  * one uart channel device which will be opened.
62  * For master channel, create two threads, one thread
63  * is to listen and wait sync messaage from slave channel, another thread
64  * is to poll message from slave channel.
65  * For slave channel, create one thread to send sync message
66  * to master channel every 5 second until acked sync
67  * message is received from master channel and poll meessage from master channel.
68  *
69  * @param uart  point to uart server
70  * @param path	start address of the name of the device which will
71  *              be opened
72  * @param fn	the handler of handling message
73  */
74 struct channel_dev *create_uart_channel_dev(struct uart_channel *c, char *path, data_handler_f *fn);
75 
76 /**
77  * @brief Wait uart channel devices threads to exit
78  */
79 void wait_uart_channel_devs_threads(struct uart_channel *c);
80 /**
81  * @brief Destroy uart channel and release channel device instance
82  */
83 void deinit_uart_channel(struct uart_channel *c);
84 /**
85  * @brief Wait to connect device in uart channel
86  *
87  * Wait sync message from slave channel device, parse slave channel device
88  * indentifier from sync message, then add channel device into uart channel
89  * device connection list.
90  */
91 void *listen_uart_channel_dev(void *arg);
92 /**
93  * @brief Wait to connect device in the uart channel
94  *
95  * Send sync message every 5 second and wait acked sync message from master
96  * channel device, add uart channel device instance into uart connection list.
97  */
98 void *connect_uart_channel_dev(void *arg);
99 /**
100  * @brief Poll and dispatch message received from uart channel
101  *
102  * If resend time is set, this interface will resend message unit the ACK message
103  * is received.
104  */
105 void *poll_and_dispatch_uart_channel_events(void *arg);
106 /**
107  * @brief Find uart channel device instance according to fd
108  */
109 struct channel_dev *find_uart_channel_dev(struct uart_channel *c, int fd);
110 /**
111  * @brief Find uart channel device instance according to device name
112  */
113 struct channel_dev *find_uart_channel_dev_by_name(struct uart_channel *c, char *name);
114 /**
115  * @brief Disconnect uart channel device instance
116  */
117 void disconnect_uart_channel_dev(struct channel_dev *c_dev, struct uart_channel *c);
118 /**
119  * @brief Stop to listen uart channel device
120  */
121 void stop_listen_uart_channel_dev(struct uart_channel *c);
122 /**
123  * @brief Set the uart channel device resending buffer and resending time
124  *
125  * If ACK message is not received during specified time, resend
126  * message.
127  */
128 void start_uart_channel_dev_resend(struct channel_dev *c_dev, char *resend_buf, unsigned int resend_time);
129 /**
130  * @brief Start to resend for all connected uart channel devices
131  */
132 void start_all_uart_channel_dev_resend(struct uart_channel *c, char *msg, unsigned int resend_time);
133 /**
134  * @brief Stop the uart channel device resending buffer and resending time
135  */
136 void stop_uart_channel_dev_resend(struct channel_dev *c_dev);
137 /**
138  * @brief Broadcast message to each connected uart channel device
139  */
140 void notify_all_connected_uart_channel_dev(struct uart_channel *c, char *msg);
141 /**
142  * @brief Check whether uart channel connection list is empty or not
143  */
144 bool is_uart_channel_connection_list_empty(struct uart_channel *c);
145 #endif
146 
147