1 /*
2  * Copyright (c) 2025 Linumiz GmbH
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "ocpp_i.h"
8 
9 LOG_MODULE_REGISTER(ocpp_rpc, CONFIG_OCPP_LOG_LEVEL);
10 
11 #define	OCPP_WAMP_RPC_TYPE_IDX 1
12 
ocpp_send_to_server(struct ocpp_wamp_rpc_msg * snd,k_timeout_t timeout)13 int ocpp_send_to_server(struct ocpp_wamp_rpc_msg *snd, k_timeout_t timeout)
14 {
15 	int ret;
16 	int sock;
17 	struct ocpp_info *ctx  = snd->ctx;
18 
19 	switch (snd->msg[OCPP_WAMP_RPC_TYPE_IDX]) {
20 	case OCPP_WAMP_RPC_REQ:
21 		/* ocpp spec - allow only one active call at a time
22 		 * release lock on response received from CS or timeout
23 		 */
24 		ret = k_mutex_lock(snd->sndlock, timeout);
25 		if (ret < 0) {
26 			return ret;
27 		}
28 		k_poll_signal_reset(snd->rspsig);
29 		break;
30 
31 	case OCPP_WAMP_RPC_RESP:
32 	case OCPP_WAMP_RPC_ERR:
33 		break;
34 
35 	default:
36 		return -EINVAL;
37 	}
38 
39 	k_mutex_lock(&ctx->ilock, K_FOREVER);
40 	sock = ctx->ui.wssock;
41 	k_mutex_unlock(&ctx->ilock);
42 	if (sock < 0) {
43 		ret = -EAGAIN;
44 		goto unlock;
45 	}
46 
47 	ret = websocket_send_msg(sock, snd->msg, snd->msg_len,
48 				 WEBSOCKET_OPCODE_DATA_TEXT, true,
49 				 true, 5000); /* fixme timeout */
50 	if (ret < 0) {
51 		goto unlock;
52 	}
53 
54 	if (snd->rspsig != NULL) {
55 		struct k_poll_event events[1] = {
56 			K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL,
57 					K_POLL_MODE_NOTIFY_ONLY,
58 					snd->rspsig),
59 		};
60 
61 		ret = k_poll(events, 1, timeout);
62 		goto unlock;
63 	}
64 
65 	return 0;
66 
67 unlock:
68 	if (snd->sndlock != NULL) {
69 		k_mutex_unlock(snd->sndlock);
70 	}
71 
72 	return ret;
73 }
74 
ocpp_receive_from_server(struct ocpp_wamp_rpc_msg * rcv,uint32_t * msg_type,uint32_t timeout)75 int ocpp_receive_from_server(struct ocpp_wamp_rpc_msg *rcv, uint32_t *msg_type,
76 			     uint32_t timeout)
77 {
78 	int ret;
79 	int sock;
80 	uint64_t remaining = 0;
81 	struct ocpp_info *ctx  = rcv->ctx;
82 
83 	k_mutex_lock(&ctx->ilock, K_MSEC(timeout));
84 	sock = ctx->ui.wssock;
85 	k_mutex_unlock(&ctx->ilock);
86 	if (sock < 0) {
87 		return -EAGAIN;
88 	}
89 
90 	ret = websocket_recv_msg(sock, rcv->msg,
91 				 rcv->msg_len,
92 				 msg_type,
93 				 &remaining,
94 				 timeout);
95 
96 	return ret;
97 }
98