/*
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef ZEPHYR_SUBSYS_BLUETOOTH_MESH_SUBNET_H_
#define ZEPHYR_SUBSYS_BLUETOOTH_MESH_SUBNET_H_

#include <stdint.h>
#include <sys/types.h>
#include <net/buf.h>
#include <zephyr.h>

#define BT_MESH_NET_FLAG_KR       BIT(0)
#define BT_MESH_NET_FLAG_IVU      BIT(1)

#define BT_MESH_KR_NORMAL         0x00
#define BT_MESH_KR_PHASE_1        0x01
#define BT_MESH_KR_PHASE_2        0x02
#define BT_MESH_KR_PHASE_3        0x03

/** Which of the two subnet.keys should be used for sending. */
#define SUBNET_KEY_TX_IDX(sub) ((sub)->kr_phase == BT_MESH_KR_PHASE_2)

struct bt_mesh_net_rx;
enum bt_mesh_key_evt;

/** Network message encryption credentials */
struct bt_mesh_net_cred {
	uint8_t nid;         /* NID */
	uint8_t enc[16];     /* EncKey */
	uint8_t privacy[16]; /* PrivacyKey */
};

/** Subnet instance. */
struct bt_mesh_subnet {
	uint32_t beacon_sent;        /* Timestamp of last sent beacon */
	uint8_t  beacons_last;       /* Number of beacons during last
				      * observation window
				      */
	uint8_t  beacons_cur;        /* Number of beaconds observed during
				      * currently ongoing window.
				      */

	uint8_t  beacon_cache[21];   /* Cached last authenticated beacon */

	uint16_t net_idx;            /* NetKeyIndex */

	uint8_t  kr_phase;           /* Key Refresh Phase */

	uint8_t  node_id;            /* Node Identity State */
	uint32_t node_id_start;      /* Node Identity started timestamp */

	uint8_t  auth[8];            /* Beacon Authentication Value */

	struct bt_mesh_subnet_keys {
		bool valid;
		uint8_t net[16];       /* NetKey */
		struct bt_mesh_net_cred msg;
		uint8_t net_id[8];     /* Network ID */
	#if defined(CONFIG_BT_MESH_GATT_PROXY)
		uint8_t identity[16];  /* IdentityKey */
	#endif
		uint8_t beacon[16];    /* BeaconKey */
	} keys[2];
};

/** Subnet callback structure. Instantiate with @ref BT_MESH_SUBNET_CB */
struct bt_mesh_subnet_cb {
	void (*evt_handler)(struct bt_mesh_subnet *subnet,
			    enum bt_mesh_key_evt evt);
};

/** @def BT_MESH_SUBNET_CB
 *
 *  @brief Register a subnet event callback.
 *
 *  @param _handler Handler function, see @ref bt_mesh_subnet_cb::evt_handler.
 */
#define BT_MESH_SUBNET_CB_DEFINE(_handler)                                     \
	static const Z_STRUCT_SECTION_ITERABLE(                                \
		bt_mesh_subnet_cb, _CONCAT(bt_mesh_subnet_cb_, _handler)) = {  \
		.evt_handler = (_handler),                                     \
	}

/** @brief Reset all Network keys. */
void bt_mesh_net_keys_reset(void);

/** @brief Call cb on every valid Subnet until it returns a non-zero value.
 *
 *  @param cb Callback to call, or NULL to return first valid subnet.
 *  @param cb_data Callback data to pass to callback.
 *
 *  @return Subnet that returned non-zero value.
 */
struct bt_mesh_subnet *bt_mesh_subnet_find(int (*cb)(struct bt_mesh_subnet *sub,
						     void *cb_data),
					   void *cb_data);

/** @brief Iterate through all valid Subnets.
 *
 *  @param cb Callback to call on every Subnet.
 *
 *  @returns The number of valid subnets.
 */
size_t bt_mesh_subnet_foreach(void (*cb)(struct bt_mesh_subnet *sub));

/** @brief Get the next valid Subnet.
 *
 *  If there's only one valid Subnet, this will be returned on every call.
 *
 *  @param sub Previous Subnet, or NULL to get the first valid.
 *
 *  @returns Gets the next valid Subnet after @c sub, or NULL if there are no
 *           valid Subnets.
 */
struct bt_mesh_subnet *bt_mesh_subnet_next(struct bt_mesh_subnet *sub);

/** @brief Get a pointer to the Subnet with the given index.
 *
 *  @param net_idx Network index to look for.
 *
 *  @returns Subnet with index @c net_idx, or NULL if no such Subnet is known.
 */
struct bt_mesh_subnet *bt_mesh_subnet_get(uint16_t net_idx);

/** @brief Initialize a new Subnet.
 *
 *  @param net_idx Network index of the Subnet.
 *  @param kr_phase Key refresh phase the Subnet should be in.
 *  @param key The current network key for the Subnet.
 *  @param new_key New network key, if available.
 *
 *  @returns 0 on success, or (negative) error code on failure.
 */
int bt_mesh_subnet_set(uint16_t net_idx, uint8_t kr_phase,
		       const uint8_t key[16], const uint8_t new_key[16]);

/** @brief Create Friendship credentials.
 *
 *  @param cred Credential object to create.
 *  @param lpn_addr Address of the LPN node in the friendship.
 *  @param frnd_addr Address of the Friend node in the friendship.
 *  @param lpn_counter The LPN's counter parameter.
 *  @param frnd_counter The Friend node's counter parameter.
 *  @param key Network key to create the Friendship credentials for.
 *
 *  @returns 0 on success, or (negative) error code on failure.
 */
int bt_mesh_friend_cred_create(struct bt_mesh_net_cred *cred,
			       uint16_t lpn_addr, uint16_t frnd_addr,
			       uint16_t lpn_counter, uint16_t frnd_counter,
			       const uint8_t key[16]);

/** @brief Iterate through all valid network credentials to decrypt a message.
 *
 *  @param rx Network RX parameters, passed to the callback.
 *  @param in Input message buffer, passed to the callback.
 *  @param out Output message buffer, passed to the callback.
 *  @param cb Callback to call for each known network credential. Iteration
 *            stops when this callback returns @c true.
 *
 *  @returns Whether any of the credentials got a @c true return from the
 *           callback.
 */
bool bt_mesh_net_cred_find(struct bt_mesh_net_rx *rx, struct net_buf_simple *in,
			   struct net_buf_simple *out,
			   bool (*cb)(struct bt_mesh_net_rx *rx,
				      struct net_buf_simple *in,
				      struct net_buf_simple *out,
				      const struct bt_mesh_net_cred *cred));

/** @brief Get the network flags of the given Subnet.
 *
 *  @param sub Subnet to get the network flags of.
 *
 *  @returns A bitmap of @ref BT_MESH_NET_FLAG_KR and @ref BT_MESH_NET_FLAG_IVU.
 */
uint8_t bt_mesh_net_flags(struct bt_mesh_subnet *sub);

/** @brief Process a Key Refresh event from a beacon.
 *
 *  @param sub Subnet the Key Refresh was received on.
 *  @param kr_flag Key Refresh flag.
 *  @param new_key Whether the Key Refresh event was received on the new key
 *                 set.
 */
void bt_mesh_kr_update(struct bt_mesh_subnet *sub, bool kr_flag, bool new_key);

/** @brief Check whether the Subnet has the refreshed keys.
 *
 *  @param sub Subnet.
 *
 *  @returns Whether the Subnet's second key is valid.
 */
static inline bool
bt_mesh_subnet_has_new_key(const struct bt_mesh_subnet *sub)
{
	return sub->kr_phase != BT_MESH_KR_NORMAL;
}

/** @brief Store the Subnet information in persistent storage.
 *
 * @param net_idx Network index to store.
 */
void bt_mesh_subnet_store(uint16_t net_idx);

/** @brief Store the pending Subnets in persistent storage. */
void bt_mesh_subnet_pending_store(void);

#endif /* ZEPHYR_SUBSYS_BLUETOOTH_MESH_SUBNET_H_ */
