/* * Copyright (c) 2024 A Labs GmbH * Copyright (c) 2024 tado GmbH * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include #include #include #include LOG_MODULE_REGISTER(lorawan_emul, CONFIG_LORAWAN_LOG_LEVEL); static bool lorawan_adr_enable; static sys_slist_t dl_callbacks; static DeviceClass_t current_class; static lorawan_battery_level_cb_t battery_level_cb; static lorawan_dr_changed_cb_t dr_changed_cb; static lorawan_uplink_cb_t uplink_cb; /* implementation required by the soft-se (software secure element) */ void BoardGetUniqueId(uint8_t *id) { /* Do not change the default value */ } void lorawan_emul_send_downlink(uint8_t port, bool data_pending, int16_t rssi, int8_t snr, uint8_t len, const uint8_t *data) { struct lorawan_downlink_cb *cb; /* Iterate over all registered downlink callbacks */ SYS_SLIST_FOR_EACH_CONTAINER(&dl_callbacks, cb, node) { if ((cb->port == LW_RECV_PORT_ANY) || (cb->port == port)) { cb->cb(port, data_pending, rssi, snr, len, data); } } } int lorawan_join(const struct lorawan_join_config *join_cfg) { return 0; } int lorawan_set_class(enum lorawan_class dev_class) { switch (dev_class) { case LORAWAN_CLASS_A: current_class = CLASS_A; break; case LORAWAN_CLASS_B: LOG_ERR("Class B not supported yet!"); return -ENOTSUP; case LORAWAN_CLASS_C: current_class = CLASS_C; break; default: return -EINVAL; } return 0; } int lorawan_set_datarate(enum lorawan_datarate dr) { ARG_UNUSED(dr); /* Bail out if using ADR */ if (lorawan_adr_enable) { return -EINVAL; } return 0; } void lorawan_get_payload_sizes(uint8_t *max_next_payload_size, uint8_t *max_payload_size) { LoRaMacTxInfo_t tx_info; /* QueryTxPossible cannot fail */ (void)LoRaMacQueryTxPossible(0, &tx_info); *max_next_payload_size = tx_info.MaxPossibleApplicationDataSize; *max_payload_size = tx_info.CurrentPossiblePayloadSize; } enum lorawan_datarate lorawan_get_min_datarate(void) { return LORAWAN_DR_0; } void lorawan_enable_adr(bool enable) { lorawan_adr_enable = enable; } int lorawan_set_conf_msg_tries(uint8_t tries) { return 0; } int lorawan_send(uint8_t port, uint8_t *data, uint8_t len, enum lorawan_message_type type) { if (data == NULL) { return -EINVAL; } if (uplink_cb != NULL) { uplink_cb(port, len, data); } return 0; } void lorawan_register_battery_level_callback(lorawan_battery_level_cb_t cb) { battery_level_cb = cb; } void lorawan_register_downlink_callback(struct lorawan_downlink_cb *cb) { sys_slist_append(&dl_callbacks, &cb->node); } void lorawan_register_dr_changed_callback(lorawan_dr_changed_cb_t cb) { dr_changed_cb = cb; } int lorawan_start(void) { return 0; } static int lorawan_init(void) { sys_slist_init(&dl_callbacks); return 0; } void lorawan_emul_register_uplink_callback(lorawan_uplink_cb_t cb) { uplink_cb = cb; } SYS_INIT(lorawan_init, POST_KERNEL, 0);