diff --git a/include/osmocom/pcu/pcuif_proto.h b/include/osmocom/pcu/pcuif_proto.h index 944f3644..88dc09ec 100644 --- a/include/osmocom/pcu/pcuif_proto.h +++ b/include/osmocom/pcu/pcuif_proto.h @@ -4,6 +4,7 @@ #include #define PCU_IF_VERSION 0x07 +#define TXT_MAX_LEN 128 /* msg_type */ #define PCU_IF_MSG_DATA_REQ 0x00 /* send data to given channel */ @@ -15,6 +16,7 @@ #define PCU_IF_MSG_ACT_REQ 0x40 /* activate/deactivate PDCH */ #define PCU_IF_MSG_TIME_IND 0x52 /* GSM time indication */ #define PCU_IF_MSG_PAG_REQ 0x60 /* paging request */ +#define PCU_IF_MSG_TXT_IND 0x70 /* Text indication for BTS */ /* sapi */ #define PCU_IF_SAPI_RACH 0x01 /* channel request on CCCH */ @@ -42,6 +44,16 @@ #define PCU_IF_FLAG_MCS8 (1 << 27) #define PCU_IF_FLAG_MCS9 (1 << 28) +enum gsm_pcu_if_text_type { + PCU_VERSION, + PCU_OML_ALERT, +}; + +struct gsm_pcu_if_txt_ind { + uint8_t type; /* gsm_pcu_if_text_type */ + char text[TXT_MAX_LEN]; /* Text to be transmitted to BTS */ +} __attribute__ ((packed)); + struct gsm_pcu_if_data { uint8_t sapi; uint8_t len; @@ -150,6 +162,7 @@ struct gsm_pcu_if { struct gsm_pcu_if_data data_ind; struct gsm_pcu_if_rts_req rts_req; struct gsm_pcu_if_rach_ind rach_ind; + struct gsm_pcu_if_txt_ind txt_ind; struct gsm_pcu_if_info_ind info_ind; struct gsm_pcu_if_act_req act_req; struct gsm_pcu_if_time_ind time_ind; diff --git a/src/encoding.cpp b/src/encoding.cpp index ea38b77f..2f052a48 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -320,6 +320,13 @@ int Encoding::write_immediate_assignment_reject( return plen; } +static inline void log_alert_exit(const char * error) +{ + LOGP(DRLCMACUL, LOGL_ERROR, error); + pcu_tx_txt_ind(PCU_OML_ALERT, error); + exit(1); +} + /* * Immediate assignment, sent on the CCCH/AGCH * see GSM 04.08, 9.1.18 and GSM 44.018, 9.1.18 + 10.5.2.16 @@ -374,11 +381,10 @@ int Encoding::write_immediate_assignment( // A zero-length LV. Just write L=0. bitvec_write_field(dest, wp,0,8); - if ((wp % 8)) { - LOGP(DRLCMACUL, LOGL_ERROR, "Length of IMM.ASS without rest " - "octets is not multiple of 8 bits, PLEASE FIX!\n"); - exit (0); - } + if ((wp % 8)) + log_alert_exit("Length of IMM.ASS without rest octets is not " + "multiple of 8 bits, PLEASE FIX!\n"); + plen = wp / 8; if (downlink) @@ -618,11 +624,11 @@ int Encoding::write_paging_request(bitvec * dest, uint8_t *ptmsi, uint16_t ptmsi { bitvec_write_field(dest, wp,ptmsi[i],8); // PTMSI } - if ((wp % 8)) { - LOGP(DRLCMACUL, LOGL_ERROR, "Length of PAG.REQ without rest " - "octets is not multiple of 8 bits, PLEASE FIX!\n"); - exit (0); - } + + if ((wp % 8)) + log_alert_exit("Length of PAG.REQ without rest octets is not " + "multiple of 8 bits, PLEASE FIX!\n"); + plen = wp / 8; bitvec_write_field(dest, wp,0x0,1); // "L" NLN(PCH) = off bitvec_write_field(dest, wp,0x0,1); // "L" Priority1 = off diff --git a/src/osmobts_sock.cpp b/src/osmobts_sock.cpp index d542b669..d7e55e7c 100644 --- a/src/osmobts_sock.cpp +++ b/src/osmobts_sock.cpp @@ -287,6 +287,9 @@ int pcu_l1if_open(void) pcu_sock_state = state; + LOGP(DL1IF, LOGL_INFO, "Sending version %s to BTS.\n", PACKAGE_VERSION); + pcu_tx_txt_ind(PCU_VERSION, "%s", PACKAGE_VERSION); + return 0; } diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index b8925979..c16ac0c4 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -73,6 +73,42 @@ struct msgb *pcu_msgb_alloc(uint8_t msg_type, uint8_t bts_nr) return msg; } +const struct value_string gsm_pcu_if_text_type_names[] = { + OSMO_VALUE_STRING(PCU_VERSION), + OSMO_VALUE_STRING(PCU_OML_ALERT), + { 0, NULL } +}; + +int pcu_tx_txt_ind(enum gsm_pcu_if_text_type t, const char *fmt, ...) +{ + struct gsm_pcu_if *pcu_prim; + struct gsm_pcu_if_txt_ind *txt; + va_list ap; + char *rep; + struct msgb *msg = pcu_msgb_alloc(PCU_IF_MSG_TXT_IND, 0); + if (!msg) + return -ENOMEM; + + pcu_prim = (struct gsm_pcu_if *) msg->data; + txt = &pcu_prim->u.txt_ind; + txt->type = t; + + va_start(ap, fmt); + rep = talloc_vasprintf(tall_pcu_ctx, fmt, ap); + va_end(ap); + + if (!rep) + return -ENOMEM; + + osmo_strlcpy(txt->text, rep, TXT_MAX_LEN); + talloc_free(rep); + + LOGP(DL1IF, LOGL_INFO, "Sending %s TXT as %s to BTS\n", txt->text, + get_value_string(gsm_pcu_if_text_type_names, t)); + + return pcu_sock_send(msg); +} + static int pcu_tx_act_req(uint8_t trx, uint8_t ts, uint8_t activate) { struct msgb *msg; diff --git a/src/pcu_l1_if.h b/src/pcu_l1_if.h index eaa01436..1618260c 100644 --- a/src/pcu_l1_if.h +++ b/src/pcu_l1_if.h @@ -29,6 +29,7 @@ extern "C" { #include #include #include +#include #ifdef __cplusplus } #endif @@ -131,6 +132,8 @@ void pcu_l1if_tx_agch(bitvec * block, int len); void pcu_l1if_tx_pch(bitvec * block, int plen, const char *imsi); +int pcu_tx_txt_ind(enum gsm_pcu_if_text_type t, const char *fmt, ...); + int pcu_l1if_open(void); void pcu_l1if_close(void);