/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#ifndef H_BLE_LL_SCHED_
#define H_BLE_LL_SCHED_

#ifdef __cplusplus
extern "C" {
#endif

/* Time per BLE scheduler slot */
#define BLE_LL_SCHED_USECS_PER_SLOT   (1250)

/*
 * Worst case time needed for scheduled advertising item. This is the longest
 * possible time to receive a scan request and send a scan response (with the
 * appropriate IFS time between them). This number is calculated using the
 * following formula: IFS + SCAN_REQ + IFS + SCAN_RSP = 150 + 176 + 150 + 376.
 * Note: worst case time to tx adv, rx scan req and send scan rsp is 1228 usecs.
 * This assumes maximum sized advertising PDU and scan response PDU.
 *
 * For connectable advertising events no scan request is allowed. In this case
 * we just need to receive a connect request PDU: IFS + CONNECT_REQ = 150 + 352.
 * Note: worst-case is 376 + 150 + 352 = 878 usecs
 *
 * NOTE: The advertising PDU transmit time is NOT included here since we know
 * how long that will take (worst-case is 376 usecs).
 */
#define BLE_LL_SCHED_ADV_MAX_USECS          (852)
#define BLE_LL_SCHED_DIRECT_ADV_MAX_USECS   (502)
#define BLE_LL_SCHED_MAX_ADV_PDU_USECS      (376)

/*
 * This is the offset from the start of the scheduled item until the actual
 * tx/rx should occur, in ticks.
 */
extern uint8_t g_ble_ll_sched_offset_ticks;

/*
 * This is the number of slots needed to transmit and receive a maximum
 * size PDU, including an IFS time before each. The actual time is
 * 2120 usecs for tx/rx and 150 for IFS = 4540 usecs.
 */
#define BLE_LL_SCHED_MAX_TXRX_SLOT  (4 * BLE_LL_SCHED_USECS_PER_SLOT)

/* BLE scheduler errors */
#define BLE_LL_SCHED_ERR_OVERLAP    (1)

/* Types of scheduler events */
#define BLE_LL_SCHED_TYPE_ADV       (1)
#define BLE_LL_SCHED_TYPE_SCAN      (2)
#define BLE_LL_SCHED_TYPE_CONN      (3)
#define BLE_LL_SCHED_TYPE_DTM       (5)
#define BLE_LL_SCHED_TYPE_PERIODIC  (6)
#define BLE_LL_SCHED_TYPE_SYNC      (7)
#define BLE_LL_SCHED_TYPE_SCAN_AUX  (8)
#define BLE_LL_SCHED_TYPE_BIG       (9)
#if MYNEWT_VAL(BLE_LL_EXT)
#define BLE_LL_SCHED_TYPE_EXTERNAL  (255)
#endif

/* Return values for schedule callback. */
#define BLE_LL_SCHED_STATE_RUNNING  (0)
#define BLE_LL_SCHED_STATE_DONE     (1)

/* Callback function */
struct ble_ll_sched_item;
typedef int (*sched_cb_func)(struct ble_ll_sched_item *sch);
typedef void (*sched_remove_cb_func)(struct ble_ll_sched_item *sch);

typedef int (* ble_ll_sched_preempt_cb_t)(struct ble_ll_sched_item *sch,
                                          struct ble_ll_sched_item *item);


/*
 * Schedule item
 *  sched_type: This is the type of the schedule item.
 *  enqueued: Flag denoting if item is on the scheduler list. 0: no, 1:yes
 *  remainder: # of usecs from offset till tx/rx should occur
 *  txrx_offset: Number of ticks from start time until tx/rx should occur.
 *
 */
struct ble_ll_sched_item
{
    uint8_t         sched_type;
#if MYNEWT_VAL(BLE_LL_EXT)
    uint8_t         sched_ext_type;
#endif
    uint8_t         enqueued;
    uint8_t         remainder;
    uint32_t        start_time;
    uint32_t        end_time;
    void            *cb_arg;
    sched_cb_func   sched_cb;
    TAILQ_ENTRY(ble_ll_sched_item) link;
};

/* Initialize the scheduler */
int ble_ll_sched_init(void);

int ble_ll_sched_insert(struct ble_ll_sched_item *sch, uint32_t max_delay,
                        ble_ll_sched_preempt_cb_t preempt_cb);
void ble_ll_sched_restart(void);

/* Remove item(s) from schedule */
int ble_ll_sched_rmv_elem(struct ble_ll_sched_item *sch);

void ble_ll_sched_rmv_elem_type(uint8_t type, sched_remove_cb_func remove_cb);

/* Schedule a new master connection */
struct ble_ll_conn_sm;
int ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm,
                                  struct ble_mbuf_hdr *ble_hdr, uint8_t pyld_len);

/* Schedule a new slave connection */
int ble_ll_sched_conn_periph_new(struct ble_ll_conn_sm *connsm);

struct ble_ll_adv_sm;
typedef void ble_ll_sched_adv_new_cb(struct ble_ll_adv_sm *advsm,
                                     uint32_t sch_start, void *arg);

/* Schedule a new advertising event */
int ble_ll_sched_adv_new(struct ble_ll_sched_item *sch,
                         ble_ll_sched_adv_new_cb cb, void *arg);

/* Schedule periodic advertising event */
int ble_ll_sched_periodic_adv(struct ble_ll_sched_item *sch, bool first_event);

int ble_ll_sched_sync_reschedule(struct ble_ll_sched_item *sch, uint32_t ww_us);
int ble_ll_sched_sync(struct ble_ll_sched_item *sch);

/* Reschedule an advertising event */
int ble_ll_sched_adv_reschedule(struct ble_ll_sched_item *sch,
                                uint32_t max_delay_ticks);

/* Reschedule and advertising pdu */
int ble_ll_sched_adv_resched_pdu(struct ble_ll_sched_item *sch);

/* Reschedule a connection that had previously been scheduled or that is over */
int ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm * connsm);

/**
 * Called to determine when the next scheduled event will occur.
 *
 * If there are not scheduled events this function returns 0; otherwise it
 * returns 1 and *next_event_time is set to the start time of the next event.
 *
 * @param next_event_time cputime at which next scheduled event will occur
 *
 * @return int 0: No events are scheduled 1: there is an upcoming event
 */
int ble_ll_sched_next_time(uint32_t *next_event_time);

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
int ble_ll_sched_scan_aux(struct ble_ll_sched_item *sch);
#endif

/* Stop the scheduler */
void ble_ll_sched_stop(void);

#if MYNEWT_VAL(BLE_LL_DTM)
int ble_ll_sched_dtm(struct ble_ll_sched_item *sch);
#endif

#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED)
#if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED)
void ble_ll_sched_css_set_params(uint32_t slot_us, uint32_t period_slots);
#endif
void ble_ll_sched_css_set_enabled(uint8_t enabled);
void ble_ll_sched_css_update_anchor(struct ble_ll_conn_sm *connsm);
void ble_ll_sched_css_set_conn_anchor(struct ble_ll_conn_sm *connsm);
#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED)
static inline bool
ble_ll_sched_css_is_enabled(void)
{
    return true;
}

static inline uint32_t
ble_ll_sched_css_get_slot_us(void)
{
    return MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_SLOT_US);
}

static inline uint32_t
ble_ll_sched_css_get_period_slots(void)
{
    return MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_PERIOD_SLOTS);
}

static inline uint32_t
ble_ll_sched_css_get_conn_interval_us(void)
{
    return ble_ll_sched_css_get_period_slots() *
           ble_ll_sched_css_get_slot_us() / 1250;
}
#else
bool ble_ll_sched_css_is_enabled(void);
uint32_t ble_ll_sched_css_get_slot_us(void);
uint32_t ble_ll_sched_css_get_period_slots(void);
uint32_t ble_ll_sched_css_get_conn_interval_us(void);
#endif
#endif

#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
int ble_ll_sched_iso_big(struct ble_ll_sched_item *sch, int first, int fixed);
#endif /* BLE_LL_ISO_BROADCASTER */

#ifdef __cplusplus
}
#endif

#endif /* H_LL_SCHED_ */
