aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2011-07-24 02:52:20 +0200
committerHarald Welte <laforge@gnumonks.org>2011-07-24 02:52:20 +0200
commit13df9c8a721237bcffe40ff1cfb880910cb37688 (patch)
tree9842a086ac9458a68e8e3c1fa02ce6f2f0f08a34
parent97d4c44db20fbcd4070bf058f0a537a3170ccbe7 (diff)
sysmobts: add a skeleton for codec frame processing
-rw-r--r--src/common/Makefile.am2
-rw-r--r--src/common/voice.c19
-rw-r--r--src/osmo-bts-sysmo/Makefile.am2
-rw-r--r--src/osmo-bts-sysmo/femtobts.c17
-rw-r--r--src/osmo-bts-sysmo/femtobts.h2
-rw-r--r--src/osmo-bts-sysmo/l1_if.c14
-rw-r--r--src/osmo-bts-sysmo/l1_if.h2
-rw-r--r--src/osmo-bts-sysmo/tch.c95
8 files changed, 146 insertions, 7 deletions
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 8726b005..59436a02 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -4,4 +4,4 @@ LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOTRAU_LIBS)
noinst_LIBRARIES = libbts.a
libbts_a_SOURCES = gsm_data_shared.c sysinfo.c logging.c abis.c oml.c bts.c \
- rsl.c vty.c paging.c measurement.c
+ rsl.c vty.c paging.c measurement.c voice.c
diff --git a/src/common/voice.c b/src/common/voice.c
new file mode 100644
index 00000000..5c33e680
--- /dev/null
+++ b/src/common/voice.c
@@ -0,0 +1,19 @@
+#include <errno.h>
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/trau/rtp.h>
+
+#include <osmo-bts/gsm_data.h>
+
+/* input of an uplink received GSM codec frame
+ * this is called by the BTS L1 code after a uplink voice frame was
+ * received and has to be transmitted towards the TRAU */
+int lchan_codec_up(struct gsm_lchan *lchan, struct msgb *msg)
+{
+ struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
+
+ if (!rs)
+ return -ENODEV;
+
+ return rtp_socket_send(rs, msg);
+}
diff --git a/src/osmo-bts-sysmo/Makefile.am b/src/osmo-bts-sysmo/Makefile.am
index 034a4c58..6172d380 100644
--- a/src/osmo-bts-sysmo/Makefile.am
+++ b/src/osmo-bts-sysmo/Makefile.am
@@ -4,7 +4,7 @@ LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOTRAU_
bin_PROGRAMS = sysmobts sysmobts-remote l1fwd-proxy
-COMMON_SOURCES = main.c femtobts.c l1_if.c oml.c bts_model.c sysmobts_vty.c
+COMMON_SOURCES = main.c femtobts.c l1_if.c oml.c bts_model.c sysmobts_vty.c tch.c
sysmobts_SOURCES = $(COMMON_SOURCES) l1_transp_hw.c
sysmobts_LDADD = $(top_builddir)/src/common/libbts.a $(LDADD)
diff --git a/src/osmo-bts-sysmo/femtobts.c b/src/osmo-bts-sysmo/femtobts.c
index 70493703..47d6393d 100644
--- a/src/osmo-bts-sysmo/femtobts.c
+++ b/src/osmo-bts-sysmo/femtobts.c
@@ -219,3 +219,20 @@ const struct value_string femtobts_tracef_names[29] = {
{ DBG_STATUS, "STATUS" },
{ 0, NULL }
};
+
+const struct value_string femtobts_tch_pl_names[] = {
+ { GsmL1_TchPlType_NA, "N/A" },
+ { GsmL1_TchPlType_Fr, "FR" },
+ { GsmL1_TchPlType_Hr, "HR" },
+ { GsmL1_TchPlType_Amr, "AMR(IF2)" },
+ { GsmL1_TchPlType_Amr_SidBad, "AMR(SID BAD)" },
+ { GsmL1_TchPlType_Amr_Onset, "AMR(ONSET)" },
+ { GsmL1_TchPlType_Amr_Ratscch, "AMR(RATSCCH)" },
+ { GsmL1_TchPlType_Amr_SidUpdateInH, "AMR(SID_UPDATE INH)" },
+ { GsmL1_TchPlType_Amr_SidFirstP1, "AMR(SID_FIRST P1)" },
+ { GsmL1_TchPlType_Amr_SidFirstP2, "AMR(SID_FIRST P2)" },
+ { GsmL1_TchPlType_Amr_SidFirstInH, "AMR(SID_FIRST INH)" },
+ { GsmL1_TchPlType_Amr_RatscchMarker, "AMR(RATSCCH MARK)" },
+ { GsmL1_TchPlType_Amr_RatscchData, "AMR(RATSCCH DATA)" },
+ { 0, NULL }
+};
diff --git a/src/osmo-bts-sysmo/femtobts.h b/src/osmo-bts-sysmo/femtobts.h
index d61e4b8e..604a0593 100644
--- a/src/osmo-bts-sysmo/femtobts.h
+++ b/src/osmo-bts-sysmo/femtobts.h
@@ -27,4 +27,6 @@ const struct value_string femtobts_l1status_names[GSML1_STATUS_NUM+1];
const struct value_string femtobts_tracef_names[29];
+const struct value_string femtobts_tch_pl_names[];
+
#endif /* FEMTOBTS_H */
diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c
index 16fa4cd1..c97436e6 100644
--- a/src/osmo-bts-sysmo/l1_if.c
+++ b/src/osmo-bts-sysmo/l1_if.c
@@ -402,7 +402,8 @@ static int process_meas_res(struct gsm_lchan *lchan, GsmL1_MeasParam_t *m)
return lchan_new_ul_meas(lchan, &ulm);
}
-static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_ind)
+static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_ind,
+ struct msgb *l1p_msg)
{
struct osmo_phsap_prim pp;
struct gsm_lchan *lchan;
@@ -461,8 +462,8 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i
break;
case GsmL1_Sapi_TchF:
case GsmL1_Sapi_TchH:
- /* FIXME: TCH speech frame handling */
- rc = 0;
+ /* TCH speech frame handling */
+ rc = l1if_tch_rx(lchan, l1p_msg);
break;
default:
LOGP(DL1C, LOGL_NOTICE, "Rx PH-DATA.ind for unknown L1 SAPI %s\n",
@@ -524,7 +525,7 @@ static int l1if_handle_ind(struct femtol1_hdl *fl1, struct msgb *msg)
rc = handle_ph_readytosend_ind(fl1, &l1p->u.phReadyToSendInd);
break;
case GsmL1_PrimId_PhDataInd:
- rc = handle_ph_data_ind(fl1, &l1p->u.phDataInd);
+ rc = handle_ph_data_ind(fl1, &l1p->u.phDataInd, msg);
break;
case GsmL1_PrimId_PhRaInd:
rc = handle_ph_ra_ind(fl1, &l1p->u.phRaInd);
@@ -533,7 +534,10 @@ static int l1if_handle_ind(struct femtol1_hdl *fl1, struct msgb *msg)
break;
}
- msgb_free(msg);
+ /* Special return value '1' means: do not free */
+ if (rc != 1)
+ msgb_free(msg);
+
return rc;
}
diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h
index 3bba3998..c47fd1fa 100644
--- a/src/osmo-bts-sysmo/l1_if.h
+++ b/src/osmo-bts-sysmo/l1_if.h
@@ -53,4 +53,6 @@ struct msgb *sysp_msgb_alloc(void);
uint32_t l1if_lchan_to_hLayer2(struct gsm_lchan *lchan);
struct gsm_lchan *l1if_hLayer2_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer2);
+int l1if_tch_rx(struct gsm_lchan *lchan, struct msgb *l1p_msg);
+
#endif /* _FEMTO_L1_H */
diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c
new file mode 100644
index 00000000..87de8437
--- /dev/null
+++ b/src/osmo-bts-sysmo/tch.c
@@ -0,0 +1,95 @@
+/* Traffic channel support for Sysmocom BTS L1 */
+
+/* (C) 2011 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdint.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/select.h>
+#include <osmocom/core/timer.h>
+#include <osmocom/gsm/gsm_utils.h>
+
+#include <osmo-bts/logging.h>
+#include <osmo-bts/bts.h>
+#include <osmo-bts/gsm_data.h>
+#include <osmo-bts/measurement.h>
+
+#include <sysmocom/femtobts/femtobts.h>
+#include <sysmocom/femtobts/gsml1prim.h>
+#include <sysmocom/femtobts/gsml1const.h>
+#include <sysmocom/femtobts/gsml1types.h>
+
+#include "femtobts.h"
+#include "l1_if.h"
+
+int l1if_tch_rx(struct gsm_lchan *lchan,
+ struct msgb *l1p_msg)
+{
+ GsmL1_Prim_t *l1p = msgb_l1prim(l1p_msg);
+ GsmL1_PhDataInd_t *data_ind = &l1p->u.phDataInd;
+ uint8_t payload_type = data_ind->msgUnitParam.u8Buffer[0];
+ uint8_t *payload = data_ind->msgUnitParam.u8Buffer + 1;
+ uint8_t payload_len;
+
+ if (data_ind->msgUnitParam.u8Size < 1) {
+ LOGP(DL1C, LOGL_ERROR, "%s Rx Payload size 0\n",
+ gsm_lchan_name(lchan));
+ return -EINVAL;
+ }
+ payload_len = data_ind->msgUnitParam.u8Size - 1;
+
+ switch (payload_type) {
+ case GsmL1_TchPlType_Fr:
+ if (lchan->type != GSM_LCHAN_TCH_F)
+ goto err_payload_match;
+ break;
+ case GsmL1_TchPlType_Hr:
+ if (lchan->type != GSM_LCHAN_TCH_H)
+ goto err_payload_match;
+ break;
+ case GsmL1_TchPlType_Amr:
+ if (lchan->type != GSM_LCHAN_TCH_H &&
+ lchan->type != GSM_LCHAN_TCH_F)
+ goto err_payload_match;
+ default:
+ LOGP(DL1C, LOGL_NOTICE, "%s Rx Payload Type %s is unsupported\n",
+ gsm_lchan_name(lchan),
+ get_value_string(femtobts_tch_pl_names, payload_type));
+ break;
+ }
+
+ LOGP(DL1C, LOGL_DEBUG, "%s Rx codec frame (%u): %s\n", gsm_lchan_name(lchan),
+ payload_len, osmo_hexdump(payload, payload_len));
+
+ return 0;
+
+err_payload_match:
+ LOGP(DL1C, LOGL_ERROR, "%s Rx Payload Type %s incompatible with lchan\n",
+ gsm_lchan_name(lchan),
+ get_value_string(femtobts_tch_pl_names, payload_type));
+ return -EINVAL;
+}