diff options
-rw-r--r-- | .checkpatch.conf | 1 | ||||
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | COPYING (renamed from gpl-3.0.txt) | 0 | ||||
-rw-r--r-- | Makefile.am | 16 | ||||
-rw-r--r-- | README.md | 35 | ||||
-rw-r--r-- | configure.ac | 27 | ||||
-rw-r--r-- | contrib/gapk.spec.in | 2 | ||||
-rw-r--r-- | debian/changelog | 5 | ||||
-rw-r--r-- | debian/compat | 1 | ||||
-rw-r--r-- | debian/control | 37 | ||||
-rw-r--r-- | debian/copyright | 23 | ||||
-rw-r--r-- | debian/gapk.install | 1 | ||||
-rw-r--r-- | debian/libosmogapk-dev.install | 3 | ||||
-rw-r--r-- | debian/libosmogapk0.install | 1 | ||||
-rwxr-xr-x | debian/rules | 12 | ||||
-rw-r--r-- | debian/source/format | 1 | ||||
-rw-r--r-- | include/osmocom/gapk/get_cycles.h | 10 | ||||
-rw-r--r-- | libgsmhr/Makefile.am | 14 | ||||
-rwxr-xr-x | libgsmhr/fetch_sources.py | 46 | ||||
-rw-r--r-- | src/Makefile.am | 12 | ||||
-rw-r--r-- | src/fmt_rtp_amr.c | 9 | ||||
-rw-r--r-- | src/fmt_rtp_efr.c | 14 | ||||
-rw-r--r-- | src/pq_rtp.c | 24 | ||||
-rw-r--r-- | tests/Makefile.am | 2 |
24 files changed, 236 insertions, 64 deletions
diff --git a/.checkpatch.conf b/.checkpatch.conf new file mode 100644 index 0000000..58a0b87 --- /dev/null +++ b/.checkpatch.conf @@ -0,0 +1 @@ +--ignore NEW_TYPEDEFS @@ -3,8 +3,8 @@ autoscan-2.*.log configure.scan # autoreconf by-products +.version Makefile.in - aclocal.m4 autom4te.cache/ config.guess @@ -49,7 +49,7 @@ tests/*/*_test src/osmo-gapk # temporary/backup files -*.*~ +*~ .*.swp /compile .dirstamp diff --git a/Makefile.am b/Makefile.am index 0093f0e..f2a2c31 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,8 +4,6 @@ ACLOCAL_AMFLAGS = -I m4 pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libosmogapk.pc -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include - SUBDIRS = include if ENABLE_GSMHR @@ -13,3 +11,17 @@ SUBDIRS += libgsmhr endif SUBDIRS += src tests + +BUILT_SOURCES = \ + $(top_srcdir)/.version \ + $(NULL) +EXTRA_DIST = \ + git-version-gen \ + .version \ + $(NULL) + +# versioning magic +$(top_srcdir)/.version: + echo $(VERSION) > $@-t && mv $@-t $@ +dist-hook: + echo $(VERSION) > $(distdir)/.tarball-version diff --git a/README.md b/README.md new file mode 100644 index 0000000..5cf880e --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +gapk - GSM Audio Pocket Knife +============================= + +The GSM Audio Pocket Knife is a tool that can help you to convert +codec frames of all codecs in GSM networks between a variety of +different formats / representations. + +It is part of the [Osmocom](https://osmocom.org/) Open Source Mobile +Communications project. + +GIT Repository +-------------- + +You can clone from the official gapk.git repository using + + git clone https://gitea.osmocom.org/osmocom/gapk.git + +There is a web interface at <https://gitea.osmocom.org/osmocom/gapk>. + +Documentation +------------- + +Unfortunately none. + +Mailing List +------------ + +Discussions related to gapk are happening on the +openbsc@lists.osmocom.org mailing list, please see +https://lists.osmocom.org/mailman/listinfo/openbsc for subscription +options and the list archive. + +Please observe the [Osmocom Mailing List +Rules](https://osmocom.org/projects/cellular-infrastructure/wiki/Mailing_List_Rules) +when posting. diff --git a/configure.ac b/configure.ac index b16acc8..9a318bb 100644 --- a/configure.ac +++ b/configure.ac @@ -15,16 +15,12 @@ AC_CONFIG_SRCDIR([src/app_osmo_gapk.c]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_TESTDIR(tests) -AC_CONFIG_FILES([ - Makefile - src/Makefile - libgsmhr/Makefile - include/Makefile - include/gsmhr/Makefile - libosmogapk.pc - tests/atlocal - tests/Makefile -]) + +dnl patching ${archive_cmds} to affect generation of file "libtool" to fix linking with clang +AS_CASE(["$LD"],[*clang*], + [AS_CASE(["${host_os}"], + [*linux*],[archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'])]) + # Options AC_ARG_ENABLE(gsmhr, @@ -117,4 +113,13 @@ AC_TYPE_UINT8_T AC_FUNC_MALLOC AC_CHECK_FUNCS([memset]) -AC_OUTPUT([contrib/gapk.spec]) +AC_CONFIG_FILES([contrib/gapk.spec + Makefile + src/Makefile + libgsmhr/Makefile + include/Makefile + include/gsmhr/Makefile + libosmogapk.pc + tests/atlocal + tests/Makefile]) +AC_OUTPUT diff --git a/contrib/gapk.spec.in b/contrib/gapk.spec.in index e5d06ba..e0466f4 100644 --- a/contrib/gapk.spec.in +++ b/contrib/gapk.spec.in @@ -128,7 +128,7 @@ make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +) %postun -n libosmogapk%{sover} -p /sbin/ldconfig %files -%doc gpl-3.0.txt +%doc COPYING %{_bindir}/osmo-gapk %if 0%{with_gsmhr} diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..4cbf688 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +gapk (1.1) unstable; urgency=medium + + * Initial debian packaging + + -- Oliver Smith <osmith@sysmocom.de> Mon, 18 Mar 2024 13:15:22 +0100 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..f599e28 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +10 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..556bbf8 --- /dev/null +++ b/debian/control @@ -0,0 +1,37 @@ +Source: gapk +Section: net +Priority: optional +Maintainer: Osmocom team <openbsc@lists.osmocom.org> +Build-Depends: debhelper (>= 10), + dh-autoreconf, + autotools-dev, + autoconf, + automake, + libtool, + pkg-config, + libasound2-dev, + libgsm1-dev, + libosmocore-dev (>= 0.3.2) +Standards-Version: 4.1.4 +Vcs-Browser: https://gitea.osmocom.org/osmocom/gapk +Vcs-Git: https://gerrit.osmocom.org/gapk +Homepage: https://osmocom.org/projects/gapk/wiki/Gapk + +Package: gapk +Architecture: any +Multi-Arch: foreign +Depends: ${misc:Depends}, ${shlibs:Depends} +Description: GSM Audio Pocket Knife converts between GSM related codecs + +Package: libosmogapk0 +Architecture: any +Multi-Arch: same +Pre-Depends: ${misc:Pre-Depends} +Depends: ${misc:Depends}, ${shlibs:Depends} +Description: GSM Audio Pocket Knife converts between GSM related codecs + +Package: libosmogapk-dev +Section: libdevel +Architecture: any +Depends: libosmogapk0 (= ${binary:Version}), ${misc:Depends} +Description: GSM Audio Pocket Knife converts between GSM related codecs diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..8d7bd0c --- /dev/null +++ b/debian/copyright @@ -0,0 +1,23 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: gapk +Source: https://gitea.osmocom.org/osmocom/gapk + +Files: * +License: GPL-3.0+ + +License: GPL-3.0+ + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU 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 General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + . + On Debian systems, the complete text of the GNU General Public License + Version 3 can be found in `/usr/share/common-licenses/GPL-3'. diff --git a/debian/gapk.install b/debian/gapk.install new file mode 100644 index 0000000..1df36c6 --- /dev/null +++ b/debian/gapk.install @@ -0,0 +1 @@ +usr/bin/* diff --git a/debian/libosmogapk-dev.install b/debian/libosmogapk-dev.install new file mode 100644 index 0000000..ab755d6 --- /dev/null +++ b/debian/libosmogapk-dev.install @@ -0,0 +1,3 @@ +usr/include/* +usr/lib/*/pkgconfig/libosmogapk.pc +usr/lib/*/*.so diff --git a/debian/libosmogapk0.install b/debian/libosmogapk0.install new file mode 100644 index 0000000..3de3b10 --- /dev/null +++ b/debian/libosmogapk0.install @@ -0,0 +1 @@ +usr/lib/*/*.so.* diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..c854d74 --- /dev/null +++ b/debian/rules @@ -0,0 +1,12 @@ +#!/usr/bin/make -f + +%: + dh $@ --with autoreconf + +override_dh_auto_configure: + touch libgsmhr/.downloaded # Don't fetch 3GPP sources + dh_auto_configure + +# Print test results in case of a failure +override_dh_auto_test: + dh_auto_test || (find . -name testsuite.log -exec cat {} \; ; false) diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/include/osmocom/gapk/get_cycles.h b/include/osmocom/gapk/get_cycles.h index 40ac570..25376a1 100644 --- a/include/osmocom/gapk/get_cycles.h +++ b/include/osmocom/gapk/get_cycles.h @@ -103,6 +103,16 @@ static inline cycles_t get_cycles() #endif return ret & ~TICK_PRIV_BIT; } +#elif defined(__aarch64__) + +typedef unsigned long cycles_t; +static inline cycles_t get_cycles(void) +{ + cycles_t cval; + asm volatile("isb" : : : "memory"); + asm volatile("mrs %0, cntvct_el0" : "=r" (cval)); + return cval; +} #elif defined(__PPC__) #define CPU_FTR_601 0x00000100 typedef unsigned long cycles_t; diff --git a/libgsmhr/Makefile.am b/libgsmhr/Makefile.am index f36d759..ffbde21 100644 --- a/libgsmhr/Makefile.am +++ b/libgsmhr/Makefile.am @@ -1,3 +1,8 @@ +# This is _NOT_ the library release version, it's an API version. +# Please read Chapter 6 "Library interface versions" of the libtool +# documentation before making any modification +LIBVERSION = 0:0:0 + AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) AM_CFLAGS = -fPIC -Wall ${SYMBOL_VISIBILITY} @@ -6,8 +11,6 @@ EXTRA_DIST = \ patches \ $(NULL) -LIBVERSION=0:0:0 - REFSRC_PATH=refsrc REFSRC_SRC=refsrc/dtx.c refsrc/globdefs.c refsrc/host.c refsrc/sp_enc.c refsrc/sp_rom.c refsrc/vad.c refsrc/err_conc.c refsrc/homing.c refsrc/mathdp31.c refsrc/sp_dec.c refsrc/sp_frm.c refsrc/sp_sfrm.c @@ -18,10 +21,11 @@ ${REFSRC_PATH}/.downloaded: done touch $@ -$(REFSRC_SRC) libgsmhr.c: ${REFSRC_PATH}/.downloaded +$(REFSRC_SRC): ${REFSRC_PATH}/.downloaded lib_LTLIBRARIES = libgsmhr.la libgsmhr_la_SOURCES = $(REFSRC_SRC) libgsmhr.c +libgsmhr_la_LDFLAGS = -version-info $(LIBVERSION) libgsmhr_la_LIBADD = -ldl clean-local: @@ -29,3 +33,7 @@ clean-local: distclean-local: -rm -rf ${REFSRC_PATH}/ + +# exclude files downloaded by fetch_sources.py +dist-hook: + -rm -rf $(distdir)/$(REFSRC_PATH) diff --git a/libgsmhr/fetch_sources.py b/libgsmhr/fetch_sources.py index 6fb1b8e..178125c 100755 --- a/libgsmhr/fetch_sources.py +++ b/libgsmhr/fetch_sources.py @@ -1,35 +1,30 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -import urllib2 +import logging as log +import urllib.request +import io import os import sys import zipfile -try: - import cStringIO as StringIO -except: - import StringIO +URL = "http://www.3gpp.org/ftp/Specs/archive/06_series/06.06/0606-421.zip" -SRC = "http://www.3gpp.org/ftp/Specs/archive/06_series/06.06/0606-421.zip" -HDR = { - "User-Agent": "Mozilla/5.0 (X11; ArchLinux; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0", - "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", -} +def get_zipfile(data: bytes) -> zipfile.ZipFile: + return zipfile.ZipFile(io.BytesIO(data), 'r') -def get_zipfile(data): - return zipfile.ZipFile(StringIO.StringIO(data)) - -def get_subfile_data(data, filename): +def get_subfile_data(data: bytes, filename: str): + log.debug('Unpacking \'%s\'', filename) z = get_zipfile(data) return z.read(filename) def process_file(z, e): - fh = open(os.path.basename(e.filename.lower()), 'w') - d = z.read(e).replace('\r','') + log.debug('Processing file \'%s\'', e.filename.lower()) + fh = open(os.path.basename(e.filename.lower()), 'wb') + d = z.read(e).replace(b'\r', b'') fh.write(d) fh.close() @@ -38,7 +33,7 @@ def main(*args): # Args if len(args) != 2: - print "Usage: %s target_dir" % args[0] + print("Usage: %s target_dir" % args[0]) return tgt = args[1] @@ -49,9 +44,16 @@ def main(*args): os.chdir(tgt) # Get the original data - req = urllib2.Request(SRC, headers = HDR) - u = urllib2.urlopen(req) - d = u.read() + log.info('Requesting file: %s', URL) + with urllib.request.urlopen(URL) as response: + log.debug('Response code: %d', response.code) + assert response.code == 200 + + for h in ('Last-Modified', 'Content-Type', 'Content-Length'): + log.debug('%s: %s', h, response.getheader(h)) + + log.info('Downloading %d bytes...', response.length) + d = response.read() # Get DISK.zip d = get_subfile_data(d, 'DISK.zip') @@ -67,5 +69,7 @@ def main(*args): process_file(z, e) +log.basicConfig(format='[%(levelname)s] %(filename)s:%(lineno)d %(message)s', level=log.DEBUG) + if __name__ == '__main__': main(*sys.argv) diff --git a/src/Makefile.am b/src/Makefile.am index 8fdeff7..550e3b8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,19 +20,22 @@ AM_CFLAGS = \ lib_LTLIBRARIES = libosmogapk.la EXTRA_DIST = libosmogapk.map -libosmogapk_la_LDFLAGS = \ +libosmogapk_la_LIBADD = \ $(LIBOSMOCORE_LIBS) \ $(LIBOSMOCODEC_LIBS) \ ${OPENCORE_AMRNB_LIBS} \ ${LIBGSM_LIBS} \ $(LIBALSA_LIBS) \ + $(NULL) + +libosmogapk_la_LDFLAGS = \ $(LTLDFLAGS_OSMOGAPK) \ -version-info $(LIBVERSION) \ -no-undefined \ $(NULL) if ENABLE_GSMHR -libosmogapk_la_LIBADD = $(top_builddir)/libgsmhr/libgsmhr.la +libosmogapk_la_LIBADD += $(top_builddir)/libgsmhr/libgsmhr.la endif # Processing queue implementation @@ -94,10 +97,7 @@ osmo_gapk_SOURCES = \ app_osmo_gapk.c \ $(NULL) -osmo_gapk_LDFLAGS = \ - $(LIBOSMOCORE_LIBS) \ - $(NULL) - osmo_gapk_LDADD = \ libosmogapk.la \ + $(LIBOSMOCORE_LIBS) \ $(NULL) diff --git a/src/fmt_rtp_amr.c b/src/fmt_rtp_amr.c index a6a3c9f..4982c83 100644 --- a/src/fmt_rtp_amr.c +++ b/src/fmt_rtp_amr.c @@ -27,6 +27,9 @@ #include <osmocom/gapk/formats.h> #include <osmocom/gapk/utils.h> +/* AMR SID frame is according to TS 126 101 4.2.3 */ +static const uint8_t SILENCE[] = {0x80, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00}; + /* conversion function: RTP payload -> canonical format */ static int rtp_amr_from_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) @@ -42,6 +45,12 @@ rtp_amr_from_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) static int rtp_amr_to_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { + /* Detect severely damaged frames according to RFC4867 4.3.2 */ + if ((src[1] & 0x04) == 0) { + src = SILENCE; + src_len = sizeof(SILENCE); + } + /* skip Payload Header according to RFC4867 4.4.1 */ memcpy(dst, src+1, src_len-1); diff --git a/src/fmt_rtp_efr.c b/src/fmt_rtp_efr.c index 7afb1a3..214010e 100644 --- a/src/fmt_rtp_efr.c +++ b/src/fmt_rtp_efr.c @@ -30,6 +30,17 @@ #define EFR_LEN 31 #define EFR_MAGIC 0xc +/* EFR encoding starts with 0xc, if all other bits are 0 the packet is probably damaged */ +static const uint8_t DAMAGED_PACKET[EFR_LEN] = { + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +/* EFR SID frame is according to TS 101 318 5.3.2 */ +static const uint8_t SILENCE[EFR_LEN] = { + 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + /* conversion function: RTP payload -> canonical format */ static int rtp_efr_from_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) @@ -58,6 +69,9 @@ rtp_efr_to_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) return EFR_CANON_LEN; } + if (!memcmp(DAMAGED_PACKET, src, EFR_LEN)) + src = SILENCE; + for (i=0; i<(EFR_LEN-1); i++) dst[i] = (src[i] << 4) | (src[i+1] >> 4); dst[EFR_LEN-1] = src[EFR_LEN-1] << 4; diff --git a/src/pq_rtp.c b/src/pq_rtp.c index 3a09ba7..a5543a6 100644 --- a/src/pq_rtp.c +++ b/src/pq_rtp.c @@ -30,33 +30,21 @@ #include <osmocom/gapk/codecs.h> #include <osmocom/gapk/formats.h> #include <osmocom/gapk/procqueue.h> - -#ifndef __BYTE_ORDER -# ifdef __APPLE__ -# define __BYTE_ORDER __DARWIN_BYTE_ORDER -# define __LITTLE_ENDIAN __DARWIN_LITTLE_ENDIAN -# define __BIG_ENDIAN __DARWIN_BIG_ENDIAN -# else -# error "__BYTE_ORDER should be defined by someone" -# endif -#endif +#include <osmocom/core/endian.h> /* according to RFC 3550 */ struct rtp_hdr { -#if __BYTE_ORDER == __LITTLE_ENDIAN +#if OSMO_IS_LITTLE_ENDIAN uint8_t csrc_count:4, extension:1, padding:1, version:2; uint8_t payload_type:7, marker:1; -#elif __BYTE_ORDER == __BIG_ENDIAN - uint8_t version:2, - padding:1, - extension:1, - csrc_count:4; - uint8_t marker:1, - payload_type:7; +#elif OSMO_IS_BIG_ENDIAN +/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianness.py) */ + uint8_t version:2, padding:1, extension:1, csrc_count:4; + uint8_t marker:1, payload_type:7; #endif uint16_t sequence; uint32_t timestamp; diff --git a/tests/Makefile.am b/tests/Makefile.am index dee4060..e0a3c96 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -10,6 +10,8 @@ AM_CFLAGS = \ $(LIBOSMOCODEC_CFLAGS) \ $(NULL) +AM_LDFLAGS = -no-install + check_PROGRAMS = \ procqueue/pq_test \ io/pq_file_test \ |