1 /* 2 * Copyright (c) 2025 Linumiz GmbH 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef __OCPP_I_ 8 #define __OCPP_I_ 9 10 #include "string.h" 11 #include <zephyr/logging/log.h> 12 #include <zephyr/net/ocpp.h> 13 #include <zephyr/net/socket.h> 14 #include <zephyr/net/websocket.h> 15 #include <zephyr/sys/slist.h> 16 17 #if __POSIX_VISIBLE < 200809 18 char *strdup(const char *); 19 #endif 20 21 /* case-insensitive */ 22 #define CISTR20 20 23 #define CISTR25 25 24 #define CISTR500 500 25 26 #define INVALID_CONN_ID ((uint8_t) -1) 27 #define INVALID_TXN_ID ((int) -1) 28 29 #define to_session(ptr) CONTAINER_OF(ptr, struct ocpp_session, node) 30 31 enum ocpp_pdu_msg { 32 PDU_BOOTNOTIFICATION, 33 PDU_AUTHORIZE, 34 PDU_START_TRANSACTION, 35 PDU_STOP_TRANSACTION, 36 PDU_HEARTBEAT, 37 PDU_METER_VALUES, 38 PDU_CLEAR_CACHE, 39 PDU_REMOTE_START_TRANSACTION, 40 PDU_REMOTE_STOP_TRANSACTION, 41 PDU_GET_CONFIGURATION, 42 PDU_CHANGE_CONFIGURATION, 43 PDU_CHANGE_AVAILABILITY, 44 PDU_UNLOCK_CONNECTOR, 45 PDU_RESET, 46 47 PDU_MSG_END, 48 49 /* internal msg */ 50 PDU_CS_ONLINE, 51 }; 52 53 enum ocpp_key_type { 54 KEY_TYPE_BOOL = 1, 55 KEY_TYPE_INT = sizeof(int), 56 KEY_TYPE_STR, 57 KEY_TYPE_CSL, 58 }; 59 60 enum boot_status { 61 BOOT_ACCEPTED, 62 BOOT_PENDING, 63 BOOT_REJECTED 64 }; 65 66 enum ocpp_key { 67 /* core mandatory */ 68 CFG_ALLOW_OFFLINE_TX_FOR_UNKN_ID, 69 CFG_AUTH_CACHE_ENABLED, 70 CFG_AUTH_REMOTE_TX_REQ, 71 CFG_BLINK_REPEAT, 72 CFG_CLK_ALIGN_DATA_INTERVAL, 73 CFG_CONN_TIMEOUT, 74 CFG_GETCFG_MAX_KEY, 75 CFG_HEARTBEAT_INTERVAL, 76 CFG_LIGHT_INTENSITY, 77 CFG_LOCAL_AUTH_OFFLINE, 78 CFG_LOCAL_PREAUTH, 79 CFG_MAX_ENERGYON_INVL_ID, 80 CFG_MTR_VAL_ALGIN_DATA, 81 CFG_MTR_VAL_ALGIN_DATA_MAXLEN, 82 CFG_MTR_VAL_SAMPLED_DATA, 83 CFG_MTR_VAL_SAMPLED_DATA_MAXLEN, 84 CFG_MTR_VAL_SAMPLE_INTERVAL, 85 CFG_MIN_STATUS_DURATION, 86 CFG_NO_OF_CONNECTORS, 87 CFG_REST_RETRIES, 88 CFG_CONN_PHASE_ROT, 89 CFG_CONN_PHASE_ROT_MAXLEN, 90 CFG_STOP_TXN_ON_EVSIDE_DISCON, 91 CFG_STOP_TXN_ON_INVL_ID, 92 CFG_STOP_TXN_ALIGNED_DATA, 93 CFG_STOP_TXN_ALIGNED_DATA_MAXLEN, 94 CFG_SUPPORTED_FEATURE_PROFILE, 95 CFG_SUPPORTED_FEATURE_PROFILE_MAXLEN, 96 CFG_TXN_MSG_ATTEMPTS, 97 CFG_TXN_MSG_RETRY_INTERVAL, 98 CFG_UNLOCK_CONN_ON_EVSIDE_DISCON, 99 CFG_WEBSOCK_PING_INTERVAL, 100 101 /* optional */ 102 103 OCPP_CFG_END 104 }; 105 106 enum ocpp_cp_state { 107 CP_STATE_INIT, 108 CP_STATE_BOOTNOTIF, 109 CP_STATE_READY, 110 }; 111 112 enum ocpp_wamp_rpc { 113 OCPP_WAMP_RPC_REQ = '2', 114 OCPP_WAMP_RPC_RESP = '3', 115 OCPP_WAMP_RPC_ERR = '4' 116 }; 117 118 typedef int (*ocpp_msg_fp_t)(char *buf, ...); 119 120 struct boot_notif { 121 enum boot_status status; 122 int interval; 123 struct timeval date; 124 }; 125 126 struct ocpp_idtag_info { 127 char idtag[CISTR20]; 128 char p_idtag[CISTR20]; 129 enum ocpp_auth_status auth_status; 130 char exptime[CISTR25]; 131 }; 132 133 struct ocpp_upstream_info { 134 struct k_mutex ws_sndlock; /* to server */ 135 struct k_poll_signal ws_rspsig; /* wait for resp parsed */ 136 int tcpsock; 137 int wssock; 138 struct k_thread tinfo; 139 char recv_buf[CONFIG_OCPP_RECV_BUFFER_SIZE]; 140 char wsrecv_buf[CONFIG_OCPP_RECV_BUFFER_SIZE * 2]; 141 142 struct ocpp_cs_info csi; 143 }; 144 145 struct ocpp_info { 146 struct k_mutex ilock; /* internal to lib */ 147 sys_slist_t slist; /* session list */ 148 ocpp_msg_fp_t *cfn; 149 ocpp_msg_fp_t *pfn; 150 bool is_cs_offline; 151 struct k_timer hb_timer; 152 struct k_timer mtr_timer; 153 atomic_t mtr_timer_ref_cnt; 154 int hb_sec; /* heartbeat interval */ 155 struct k_msgq *msgq; 156 struct k_thread tinfo; 157 struct ocpp_upstream_info ui; 158 bool is_cs_connected; /* central system */ 159 160 ocpp_user_notify_callback_t cb; 161 void *user_data; 162 enum ocpp_cp_state state; 163 /* only for pdu message from internal thread (ocpp_internal_handler) */ 164 char pdu_buf[512]; 165 }; 166 167 struct ocpp_session { 168 struct k_mutex slock; /* session lock */ 169 char idtag[CISTR20]; 170 bool is_active; 171 uint8_t idcon; 172 int idtxn; 173 int resp_status; 174 int uid; 175 sys_snode_t node; 176 struct ocpp_info *ctx; 177 }; 178 179 union ocpp_keyval { 180 int ival; 181 char *str; 182 }; 183 184 struct ocpp_wamp_rpc_msg { 185 char *msg; 186 size_t msg_len; 187 struct ocpp_info *ctx; 188 struct k_mutex *sndlock; 189 struct k_poll_signal *rspsig; 190 }; 191 192 struct internal_msg { 193 enum ocpp_pdu_msg msgtype; 194 union ocpp_io_value usr; 195 }; 196 197 void ocpp_parser_init(ocpp_msg_fp_t **cfn, ocpp_msg_fp_t **pfn); 198 int parse_rpc_msg(char *msg, int msglen, char *uid, int uidlen, 199 int *pdu, bool *is_rsp); 200 int ocpp_send_to_server(struct ocpp_wamp_rpc_msg *snd, k_timeout_t timeout); 201 int ocpp_receive_from_server(struct ocpp_wamp_rpc_msg *rcv, uint32_t *msg_type, 202 uint32_t timeout); 203 204 int ocpp_unlock_connector(struct ocpp_info *ctx, 205 struct internal_msg *msg, char *uid); 206 int ocpp_get_configuration(enum ocpp_key key, struct ocpp_info *ctx, char *uid); 207 int ocpp_boot_notification(ocpp_session_handle_t hndl, 208 struct ocpp_cp_info *cpi); 209 int ocpp_heartbeat(ocpp_session_handle_t hndl); 210 void ocpp_get_utc_now(char utc[CISTR25]); 211 bool ocpp_session_is_valid(struct ocpp_session *sh); 212 int ocpp_remote_start_transaction(struct ocpp_info *ctx, 213 struct internal_msg *msg, 214 char *uid); 215 int ocpp_remote_stop_transaction(struct ocpp_info *ctx, 216 struct internal_msg *msg, 217 int idtxn, char *uid); 218 int ocpp_change_configuration(char *skey, struct ocpp_info *ctx, 219 char *sval, char *uid); 220 int ocpp_meter_values(ocpp_session_handle_t hndl, 221 enum ocpp_meter_measurand mes, 222 char *sval); 223 224 union ocpp_keyval *ocpp_get_key_val(enum ocpp_key key); 225 enum ocpp_key ocpp_key_to_cfg(const char *skey); 226 enum ocpp_key_type ocpp_get_keyval_type(enum ocpp_key key); 227 char *ocpp_get_key_literal(enum ocpp_key key); 228 bool ocpp_is_key_rw(enum ocpp_key key); 229 int ocpp_set_cfg_val(enum ocpp_key key, union ocpp_keyval *val); 230 int ocpp_update_cfg_val(enum ocpp_key key, union ocpp_keyval *val); 231 int ocpp_find_pdu_from_literal(const char *msg); 232 const char *ocpp_get_pdu_literal(enum ocpp_pdu_msg pdu); 233 #endif /* __OCPP_I_ */ 234