1 /*
2  * Copyright (c) 2020 Siddharth Chandrasekaran <siddharth@embedjournal.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/init.h>
9 #include <zephyr/device.h>
10 #include <zephyr/drivers/uart.h>
11 #include <zephyr/sys/ring_buffer.h>
12 #include <zephyr/logging/log.h>
13 
14 #include "osdp_common.h"
15 
16 LOG_MODULE_REGISTER(osdp, CONFIG_OSDP_LOG_LEVEL);
17 
18 #ifdef CONFIG_OSDP_SC_ENABLED
19 #ifdef CONFIG_OSDP_MODE_PD
20 #define OSDP_KEY_STRING CONFIG_OSDP_PD_SCBK
21 #else
22 #define OSDP_KEY_STRING CONFIG_OSDP_MASTER_KEY
23 #endif
24 #else
25 #define OSDP_KEY_STRING ""
26 #endif	/* CONFIG_OSDP_SC_ENABLED */
27 
28 struct osdp_device {
29 	struct ring_buf rx_buf;
30 	struct ring_buf tx_buf;
31 #ifdef CONFIG_OSDP_MODE_PD
32 	int rx_event_data;
33 	struct k_fifo rx_event_fifo;
34 #endif
35 	uint8_t rx_fbuf[OSDP_PACKET_BUF_SIZE];
36 	uint8_t tx_fbuf[OSDP_PACKET_BUF_SIZE];
37 	struct uart_config dev_config;
38 	const struct device *dev;
39 	int wait_for_mark;
40 	uint8_t last_byte;
41 };
42 
43 static struct osdp osdp_ctx;
44 static struct osdp_pd osdp_pd_ctx[CONFIG_OSDP_NUM_CONNECTED_PD];
45 static struct osdp_device osdp_device;
46 static struct k_thread osdp_refresh_thread;
47 static K_THREAD_STACK_DEFINE(osdp_thread_stack, CONFIG_OSDP_THREAD_STACK_SIZE);
48 
osdp_handle_in_byte(struct osdp_device * p,uint8_t * buf,int len)49 static void osdp_handle_in_byte(struct osdp_device *p, uint8_t *buf, int len)
50 {
51 	if (p->wait_for_mark) {
52 		/* Check for new packet beginning with [FF,53,...] sequence */
53 		if (p->last_byte == 0xFF && buf[0] == 0x53) {
54 			buf[0] = 0xFF;
55 			ring_buf_put(&p->rx_buf, buf, 1);   /* put last byte */
56 			buf[0] = 0x53;
57 			ring_buf_put(&p->rx_buf, buf, len); /* put rest */
58 			p->wait_for_mark = 0; /* Mark found. Clear flag */
59 		}
60 		p->last_byte = buf[0];
61 		return;
62 	}
63 	ring_buf_put(&p->rx_buf, buf, len);
64 }
65 
osdp_uart_isr(const struct device * dev,void * user_data)66 static void osdp_uart_isr(const struct device *dev, void *user_data)
67 {
68 	size_t len;
69 	uint8_t buf[64];
70 	struct osdp_device *p = user_data;
71 
72 	while (uart_irq_update(dev) && uart_irq_is_pending(dev)) {
73 
74 		if (uart_irq_rx_ready(dev)) {
75 			len = uart_fifo_read(dev, buf, sizeof(buf));
76 			if (len > 0) {
77 				osdp_handle_in_byte(p, buf, len);
78 			}
79 		}
80 
81 		if (uart_irq_tx_ready(dev)) {
82 			len = ring_buf_get(&p->tx_buf, buf, 1);
83 			if (!len) {
84 				uart_irq_tx_disable(dev);
85 			} else {
86 				uart_fifo_fill(dev, buf, 1);
87 			}
88 		}
89 	}
90 #ifdef CONFIG_OSDP_MODE_PD
91 	if (p->wait_for_mark == 0) {
92 		/* wake osdp_refresh thread */
93 		k_fifo_put(&p->rx_event_fifo, &p->rx_event_data);
94 	}
95 #endif
96 }
97 
osdp_uart_receive(void * data,uint8_t * buf,int len)98 static int osdp_uart_receive(void *data, uint8_t *buf, int len)
99 {
100 	struct osdp_device *p = data;
101 
102 	return (int)ring_buf_get(&p->rx_buf, buf, len);
103 }
104 
osdp_uart_send(void * data,uint8_t * buf,int len)105 static int osdp_uart_send(void *data, uint8_t *buf, int len)
106 {
107 	int sent = 0;
108 	struct osdp_device *p = data;
109 
110 	sent = (int)ring_buf_put(&p->tx_buf, buf, len);
111 	uart_irq_tx_enable(p->dev);
112 	return sent;
113 }
114 
osdp_uart_flush(void * data)115 static void osdp_uart_flush(void *data)
116 {
117 	struct osdp_device *p = data;
118 
119 	p->wait_for_mark = 1;
120 	ring_buf_reset(&p->tx_buf);
121 	ring_buf_reset(&p->rx_buf);
122 }
123 
osdp_get_ctx()124 struct osdp *osdp_get_ctx()
125 {
126 	return &osdp_ctx;
127 }
128 
osdp_build_ctx(struct osdp_channel * channel)129 static struct osdp *osdp_build_ctx(struct osdp_channel *channel)
130 {
131 	int i;
132 	struct osdp *ctx;
133 	struct osdp_pd *pd;
134 	int pd_adddres[CONFIG_OSDP_NUM_CONNECTED_PD] = {0};
135 
136 #ifdef CONFIG_OSDP_MODE_PD
137 	pd_adddres[0] = CONFIG_OSDP_PD_ADDRESS;
138 #else
139 	if (osdp_extract_address(pd_adddres)) {
140 		return NULL;
141 	}
142 #endif
143 	ctx = &osdp_ctx;
144 	ctx->num_pd = CONFIG_OSDP_NUM_CONNECTED_PD;
145 	ctx->pd = &osdp_pd_ctx[0];
146 	SET_CURRENT_PD(ctx, 0);
147 
148 	for (i = 0; i < CONFIG_OSDP_NUM_CONNECTED_PD; i++) {
149 		pd = osdp_to_pd(ctx, i);
150 		pd->idx = i;
151 		pd->seq_number = -1;
152 		pd->osdp_ctx = ctx;
153 		pd->address = pd_adddres[i];
154 		pd->baud_rate = CONFIG_OSDP_UART_BAUD_RATE;
155 		if (IS_ENABLED(CONFIG_OSDP_SKIP_MARK_BYTE)) {
156 			SET_FLAG(pd, PD_FLAG_PKT_SKIP_MARK);
157 		}
158 		memcpy(&pd->channel, channel, sizeof(struct osdp_channel));
159 		k_mem_slab_init(&pd->cmd.slab, pd->cmd.slab_buf, sizeof(union osdp_ephemeral_data),
160 				CONFIG_OSDP_PD_COMMAND_QUEUE_SIZE);
161 	}
162 	return ctx;
163 }
164 
osdp_refresh(void * arg1,void * arg2,void * arg3)165 void osdp_refresh(void *arg1, void *arg2, void *arg3)
166 {
167 	struct osdp *ctx = osdp_get_ctx();
168 
169 	while (1) {
170 #ifdef CONFIG_OSDP_MODE_PD
171 		k_fifo_get(&osdp_device.rx_event_fifo, K_FOREVER);
172 #else
173 		k_msleep(50);
174 #endif
175 		osdp_update(ctx);
176 	}
177 }
178 
osdp_init(void)179 static int osdp_init(void)
180 {
181 	int len;
182 	uint8_t c, *key = NULL, key_buf[16];
183 	struct osdp *ctx;
184 	struct osdp_device *p = &osdp_device;
185 	struct osdp_channel channel = {
186 		.send = osdp_uart_send,
187 		.recv = osdp_uart_receive,
188 		.flush = osdp_uart_flush,
189 		.data = &osdp_device,
190 	};
191 
192 #ifdef CONFIG_OSDP_MODE_PD
193 	k_fifo_init(&p->rx_event_fifo);
194 #endif
195 
196 	ring_buf_init(&p->rx_buf, sizeof(p->rx_fbuf), p->rx_fbuf);
197 	ring_buf_init(&p->tx_buf, sizeof(p->tx_fbuf), p->tx_fbuf);
198 
199 	/* init OSDP uart device */
200 	p->dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_osdp_uart));
201 	if (!device_is_ready(p->dev)) {
202 		LOG_ERR("UART dev is not ready");
203 		k_panic();
204 	}
205 
206 	/* configure uart device to 8N1 */
207 	p->dev_config.baudrate = CONFIG_OSDP_UART_BAUD_RATE;
208 	p->dev_config.data_bits = UART_CFG_DATA_BITS_8;
209 	p->dev_config.parity = UART_CFG_PARITY_NONE;
210 	p->dev_config.stop_bits = UART_CFG_STOP_BITS_1;
211 	p->dev_config.flow_ctrl = UART_CFG_FLOW_CTRL_NONE;
212 	uart_configure(p->dev, &p->dev_config);
213 
214 	uart_irq_rx_disable(p->dev);
215 	uart_irq_tx_disable(p->dev);
216 	uart_irq_callback_user_data_set(p->dev, osdp_uart_isr, p);
217 
218 	/* Drain UART fifo and set channel to wait for mark byte */
219 	while (uart_irq_rx_ready(p->dev)) {
220 		uart_fifo_read(p->dev, &c, 1);
221 	}
222 	p->wait_for_mark = 1;
223 
224 	/* Both TX and RX are interrupt driven */
225 	uart_irq_rx_enable(p->dev);
226 
227 	/* setup OSDP */
228 	ctx = osdp_build_ctx(&channel);
229 	if (ctx == NULL) {
230 		LOG_ERR("OSDP build ctx failed!");
231 		k_panic();
232 	}
233 
234 	if (IS_ENABLED(CONFIG_OSDP_SC_ENABLED)) {
235 		if (strcmp(OSDP_KEY_STRING, "NONE") != 0) {
236 			len = strlen(OSDP_KEY_STRING);
237 			if (len != 32) {
238 				LOG_ERR("Key string length must be 32");
239 				k_panic();
240 			}
241 			len = hex2bin(OSDP_KEY_STRING, 32, key_buf, 16);
242 			if (len != 16) {
243 				LOG_ERR("Failed to parse key buffer");
244 				k_panic();
245 			}
246 			key = key_buf;
247 		}
248 	}
249 
250 	if (osdp_setup(ctx, key)) {
251 		LOG_ERR("Failed to setup OSDP device!");
252 		k_panic();
253 	}
254 
255 	LOG_INF("OSDP init okay!");
256 
257 	/* kick off refresh thread */
258 	k_thread_create(&osdp_refresh_thread, osdp_thread_stack,
259 			CONFIG_OSDP_THREAD_STACK_SIZE, osdp_refresh,
260 			NULL, NULL, NULL, K_PRIO_COOP(2), 0, K_NO_WAIT);
261 	return 0;
262 }
263 
264 SYS_INIT(osdp_init, POST_KERNEL, 10);
265