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