@@ -1,6 +1,7 @@
#pragma once
#include <stdint.h>
+#include <stdbool.h>
#include <osmocom/core/utils.h>
@@ -469,11 +470,20 @@
uint8_t t3212;
} __attribute__ ((packed));
+enum gsm48_dtx_mode {
+ GSM48_DTX_MAY_BE_USED,
+ GSM48_DTX_SHALL_BE_USED,
+ GSM48_DTX_SHALL_NOT_BE_USED
+};
+
+/* Cell Options for SI6, SACCH (10.5.2.3a.2) or SI3, BCCH (Table 10.5.2.3.1),
+ 3GPP TS 44.018 */
struct gsm48_cell_options {
uint8_t radio_link_timeout:4,
dtx:2,
pwrc:1,
- spare:1;
+ /* either DN-IND or top bit of DTX IND */
+ d:1;
} __attribute__ ((packed));
/* Section 9.2.9 CM service request */
@@ -827,6 +837,9 @@
}
}
+void gsm48_set_dtx(struct gsm48_cell_options *op, enum gsm48_dtx_mode full,
+ enum gsm48_dtx_mode half, bool is_bcch);
+
#define gsm48_hdr_msg_type gsm48_hdr_msg_type_r99
/* Section 10.4 */
@@ -25,7 +25,7 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
-
+#include <stdbool.h>
#include <arpa/inet.h>
#include <osmocom/core/utils.h>
@@ -358,6 +358,50 @@
return 0;
}
+/*! \brief Set DTX mode in Cell Options IE (3GPP TS 44.018)
+ * \param[in] op Cell Options structure in which DTX parameters will be set
+ * \param[in] full Mode for full-rate channels
+ * \param[in] half Mode for half-rate channels
+ * \param[in] is_bcch Indicates if we should use 10.5.2.3.1 instead of
+ * 10.5.2.3a.2
+ *
+ * There is no space for separate DTX settings for Full and Half rate channels
+ * in BCCH - in this case full setting is used for both and half parameter is
+ * ignored.
+ */
+void gsm48_set_dtx(struct gsm48_cell_options *op, enum gsm48_dtx_mode full,
+ enum gsm48_dtx_mode half, bool is_bcch)
+{
+ if (is_bcch) {
+ switch (full) {
+ case GSM48_DTX_MAY_BE_USED:
+ op->dtx = 0;
+ return;
+ case GSM48_DTX_SHALL_BE_USED:
+ op->dtx = 1;
+ return;
+ case GSM48_DTX_SHALL_NOT_BE_USED:
+ op->dtx = 2;
+ return;
+ }
+ } else {
+ switch (full) {
+ case GSM48_DTX_MAY_BE_USED:
+ op->dtx = (half == GSM48_DTX_SHALL_BE_USED) ? 3 : 0;
+ op->d = (half == GSM48_DTX_SHALL_NOT_BE_USED) ? 0 : 1;
+ return;
+ case GSM48_DTX_SHALL_BE_USED:
+ op->dtx = (half == GSM48_DTX_MAY_BE_USED) ? 3 : 1;
+ op->d = (half == GSM48_DTX_SHALL_BE_USED) ? 1 : 0;
+ return;
+ case GSM48_DTX_SHALL_NOT_BE_USED:
+ op->dtx = 2;
+ op->d = (half == GSM48_DTX_SHALL_BE_USED) ? 1 : 0;
+ return;
+ }
+ }
+}
+
int gsm48_generate_mid_from_tmsi(uint8_t *buf, uint32_t tmsi)
{
uint32_t tmsi_be = htonl(tmsi);
@@ -162,6 +162,8 @@
gsm48_number_of_paging_subchannels;
gsm48_parse_ra;
gsm48_rr_att_tlvdef;
+gsm48_set_dtx;
+gsm48_dtx_mode;
gsm48_mi_type_name;
gsm48_mcc_mnc_to_bcd;
gsm48_mcc_mnc_from_bcd;