blob: bd542c0c5d711a49ef468e008270b7d1597c0e24 [file] [log] [blame]
Holger Hans Peter Freytherbe570812013-11-07 08:01:49 +01001/*
2 * Copyright (C) 2013 by Holger Hans Peter Freyther
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +02003 * Copyright (C) 2022 by by Sysmocom s.f.m.c. GmbH
Holger Hans Peter Freytherbe570812013-11-07 08:01:49 +01004 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Holger Hans Peter Freytherbe570812013-11-07 08:01:49 +010014 */
15
16#pragma once
17
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010018#ifdef __cplusplus
Jacob Erlbeck1eae96c2015-06-15 11:19:13 +020019extern "C" {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010020#endif
Jacob Erlbeck1eae96c2015-06-15 11:19:13 +020021
Holger Hans Peter Freytherbe570812013-11-07 08:01:49 +010022#include <stdint.h>
Holger Hans Peter Freytheracb54272013-11-07 08:15:58 +010023#include <string.h>
Pau Espin Pedrol1de68732020-03-11 14:04:52 +010024#include <time.h>
Holger Hans Peter Freytherbe570812013-11-07 08:01:49 +010025
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +020026#include <osmocom/core/linuxlist.h>
27#include <osmocom/core/msgb.h>
28
Holger Hans Peter Freytherbe570812013-11-07 08:01:49 +010029#define LLC_MAX_LEN 1543
30
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010031struct gprs_rlcmac_bts;
Jacob Erlbeck1d0a52a2015-06-02 11:28:07 +020032
Holger Hans Peter Freytherbe570812013-11-07 08:01:49 +010033/**
34 * I represent the LLC data to a MS
35 */
36struct gprs_llc {
Holger Hans Peter Freytherbe570812013-11-07 08:01:49 +010037 uint8_t frame[LLC_MAX_LEN]; /* current DL or UL frame */
Pau Espin Pedrol14633832022-03-31 19:08:07 +020038 uint16_t index; /* current write/read position of frame */
39 uint16_t length; /* len of current DL LLC_frame, 0 == no frame */
Jacob Erlbeck6dbe8222015-05-29 10:37:09 +020040};
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +020041bool llc_is_user_data_frame(const uint8_t *data, size_t len);
42
43void llc_init(struct gprs_llc *llc);
44void llc_reset(struct gprs_llc *llc);
45void llc_reset_frame_space(struct gprs_llc *llc);
46
47void llc_put_frame(struct gprs_llc *llc, const uint8_t *data, size_t len);
48void llc_put_dummy_frame(struct gprs_llc *llc, size_t req_len);
49void llc_append_frame(struct gprs_llc *llc, const uint8_t *data, size_t len);
Holger Hans Peter Freyther550bb882013-12-04 17:10:54 +010050
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010051static inline uint16_t llc_chunk_size(const struct gprs_llc *llc)
Holger Hans Peter Freytheracb54272013-11-07 08:15:58 +010052{
Pau Espin Pedrol14633832022-03-31 19:08:07 +020053 return llc->length - llc->index;
Holger Hans Peter Freythere2310262013-11-13 16:56:15 +010054}
55
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010056static inline uint16_t llc_remaining_space(const struct gprs_llc *llc)
Holger Hans Peter Freythere2310262013-11-13 16:56:15 +010057{
Pau Espin Pedrol14633832022-03-31 19:08:07 +020058 return LLC_MAX_LEN - llc->length;
Holger Hans Peter Freythere2310262013-11-13 16:56:15 +010059}
60
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010061static inline uint16_t llc_frame_length(const struct gprs_llc *llc)
Holger Hans Peter Freythere2310262013-11-13 16:56:15 +010062{
Pau Espin Pedrol14633832022-03-31 19:08:07 +020063 return llc->length;
Holger Hans Peter Freythere2310262013-11-13 16:56:15 +010064}
65
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010066static inline void llc_consume(struct gprs_llc *llc, size_t len)
Holger Hans Peter Freythere2310262013-11-13 16:56:15 +010067{
Pau Espin Pedrol14633832022-03-31 19:08:07 +020068 llc->index += len;
Holger Hans Peter Freytheracb54272013-11-07 08:15:58 +010069}
70
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010071static inline void llc_consume_data(struct gprs_llc *llc, uint8_t *data, size_t len)
Holger Hans Peter Freytheracb54272013-11-07 08:15:58 +010072{
73 /* copy and increment index */
Pau Espin Pedrol14633832022-03-31 19:08:07 +020074 memcpy(data, llc->frame + llc->index, len);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010075 llc_consume(llc, len);
Holger Hans Peter Freytheracb54272013-11-07 08:15:58 +010076}
Holger Hans Peter Freythere2310262013-11-13 16:56:15 +010077
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010078static inline bool llc_fits_in_current_frame(const struct gprs_llc *llc, uint8_t chunk_size)
Holger Hans Peter Freythere2310262013-11-13 16:56:15 +010079{
Pau Espin Pedrol14633832022-03-31 19:08:07 +020080 return llc->length + chunk_size <= LLC_MAX_LEN;
Holger Hans Peter Freythere2310262013-11-13 16:56:15 +010081}
Jacob Erlbeck6dbe8222015-05-29 10:37:09 +020082
Pau Espin Pedrolee1cb752022-03-31 19:47:33 +020083struct MetaInfo {
84 struct timespec recv_time;
85 struct timespec expire_time;
86};
87/**
88 * I store the LLC frames that come from the SGSN.
89 */
90struct gprs_llc_queue {
91 uint32_t avg_queue_delay; /* Average delay of data going through the queue */
92 size_t queue_size;
93 size_t queue_octets;
94 struct llist_head queue; /* queued LLC DL data */
95};
96
97void llc_queue_calc_pdu_lifetime(struct gprs_rlcmac_bts *bts, const uint16_t pdu_delay_csec,
98 struct timespec *tv);
99bool llc_queue_is_frame_expired(const struct timespec *tv_now, const struct timespec *tv);
100
101void llc_queue_init(struct gprs_llc_queue *q);
102void llc_queue_clear(struct gprs_llc_queue *q, struct gprs_rlcmac_bts *bts);
103void llc_queue_move_and_merge(struct gprs_llc_queue *q, struct gprs_llc_queue *o);
104void llc_queue_enqueue(struct gprs_llc_queue *q, struct msgb *llc_msg, const struct timespec *expire_time);
105struct msgb *llc_queue_dequeue(struct gprs_llc_queue *q, const struct MetaInfo **info);
106
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100107static inline size_t llc_queue_size(const struct gprs_llc_queue *q)
Jacob Erlbeck6dbe8222015-05-29 10:37:09 +0200108{
Pau Espin Pedrol14633832022-03-31 19:08:07 +0200109 return q->queue_size;
Jacob Erlbeck6dbe8222015-05-29 10:37:09 +0200110}
Jacob Erlbeck07eb6552015-06-15 11:05:44 +0200111
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100112static inline size_t llc_queue_octets(const struct gprs_llc_queue *q)
Jacob Erlbeck07eb6552015-06-15 11:05:44 +0200113{
Pau Espin Pedrol14633832022-03-31 19:08:07 +0200114 return q->queue_octets;
Jacob Erlbeck07eb6552015-06-15 11:05:44 +0200115}
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100116
117#ifdef __cplusplus
118}
119#endif