aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore42
-rw-r--r--Android.mk52
-rw-r--r--CONTRIBUTING2
-rw-r--r--Makefile.am83
-rw-r--r--README3
-rw-r--r--configure.ac165
-rw-r--r--include/samsung-ipc.h1
-rw-r--r--samsung-ipc/Makefile.am11
-rw-r--r--samsung-ipc/devices/aries/aries.c7
-rw-r--r--samsung-ipc/devices/crespo/crespo.c19
-rw-r--r--samsung-ipc/gprs.c6
-rw-r--r--samsung-ipc/ipc_strings.c409
-rw-r--r--samsung-ipc/ipc_utils.c366
-rw-r--r--samsung-ipc/modems/xmm626/xmm626_kernel_smdk4412.c16
-rw-r--r--samsung-ipc/partitions/android/android.c3
-rw-r--r--samsung-ipc/tests/Makefile.am24
-rwxr-xr-xsamsung-ipc/tests/libsamsung-ipc-test.py26
-rw-r--r--samsung-ipc/tests/partitions/android.c128
-rw-r--r--samsung-ipc/utils.c4
-rw-r--r--scripts/PKGBUILD55
-rw-r--r--scripts/guix.scm358
-rw-r--r--scripts/manifest.scm59
-rwxr-xr-xscripts/rebase-build-check-android.sh102
-rwxr-xr-xscripts/rebase-build-check-gnu-linux.sh81
-rwxr-xr-xstrict-cflags.sh35
-rw-r--r--tools/Makefile.am31
-rw-r--r--tools/https-send-sms.c205
-rw-r--r--tools/ipc-modem.c607
-rw-r--r--tools/ipc-modem/Makefile.am28
-rw-r--r--tools/ipc-modem/ipc-modem-log.c84
-rw-r--r--tools/ipc-modem/ipc-modem-log.h41
-rw-r--r--tools/ipc-modem/ipc-modem.c781
-rw-r--r--tools/ipc-modem/ipc-modem.h51
-rwxr-xr-xtools/ipc-modem/tests/ipc-modem.py145
-rw-r--r--tools/nv_data-imei.c54
-rw-r--r--tools/nv_data-imei.h2
-rw-r--r--tools/nv_data-md5.c3
-rwxr-xr-xtools/tests/nv_data-imei.py (renamed from tools/nv_data-imei.py)87
-rwxr-xr-xtools/tests/nv_data-md5.py (renamed from tools/nv_data-md5.py)36
39 files changed, 2969 insertions, 1243 deletions
diff --git a/.gitignore b/.gitignore
index 900dc6b..9bfa7dc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,42 @@
+# Tests
+/samsung-ipc/tests/libsamsung-ipc-test
+/samsung-ipc/tests/libsamsung-ipc-test.log
+/samsung-ipc/tests/libsamsung-ipc-test.trs
+/samsung-ipc/tests/test-suite.log
+/test-driver
+/tools/ipc-modem.log
+/tools/ipc-modem/tests/ipc-modem.log
+/tools/ipc-modem/tests/ipc-modem.trs
+/tools/ipc-modem/test-suite.log
+/tools/ipc-modem.trs
+/tools/nv_data-imei.log
+/tools/nv_data-imei.trs
+/tools/nv_data-md5.log
+/tools/nv_data-md5.trs
+/tools/tests/nv_data-imei.log
+/tools/tests/nv_data-imei.trs
+/tools/tests/nv_data-md5.log
+/tools/tests/nv_data-md5.trs
+/tools/test-suite.log
+valgrind.*.log
+
+# scripts/PKGBUILD
+/scripts/libsamsung-ipc-git-*.pkg.tar.xz
+/scripts/libsamsung-ipc-git-debug-*.pkg.tar.xz
+/scripts/pkg/**
+/scripts/src/**
+
+# Tools
+/tools/https-send-sms
+/tools/ipc-modem/ipc-modem
+/tools/ipc-test
+/tools/nv_data-imei
+/tools/nv_data-md5
+
+# Text editors
+\#*\#
+*~
+
Makefile.in
Makefile
*.o
@@ -29,6 +68,3 @@ INSTALL
*.pc
build
core
-ipc-modem
-ipc-test
-nv_data-md5
diff --git a/Android.mk b/Android.mk
index c0a5d35..b51f9ba 100644
--- a/Android.mk
+++ b/Android.mk
@@ -58,6 +58,7 @@ libsamsung_ipc_local_src_files := \
samsung-ipc/gen.c \
samsung-ipc/gprs.c \
samsung-ipc/ipc.c \
+ samsung-ipc/ipc_strings.c \
samsung-ipc/ipc_utils.c \
samsung-ipc/misc.c \
samsung-ipc/net.c \
@@ -112,9 +113,11 @@ libsamsung_ipc_local_c_includes := \
$(LOCAL_PATH)/samsung-ipc \
external/openssl/include
-libsamsung_local_cflags := \
- -DIPC_DEVICE_NAME=\"$(ipc_device_name)\" \
- -DDEBUG
+libsamsung_local_cflags := -DDEBUG
+
+ifneq ($(TARGET_DEVICE),)
+libsamsung_local_cflags += -DIPC_DEVICE_NAME=\"$(ipc_device_name)\"
+endif # ifneq ($(TARGET_DEVICE),)
libsamsung_ipc_local_shared_libraries := \
libutils \
@@ -158,6 +161,22 @@ LOCAL_EXPORT_C_INCLUDE_DIRS := $(local_export_c_include_dirs)
include $(BUILD_SHARED_LIBRARY)
+#######################
+# https-send-sms tool #
+#######################
+include $(CLEAR_VARS)
+include $(LOCAL_PATH)/android_versions.mk
+
+LOCAL_MODULE := https-send-sms
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := tools/https-send-sms.c
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/tools/include/glibc
+LOCAL_SHARED_LIBRARIES := libcurl
+
+include $(BUILD_EXECUTABLE)
+
##################
# ipc-modem tool #
##################
@@ -167,13 +186,34 @@ include $(LOCAL_PATH)/android_versions.mk
LOCAL_MODULE := ipc-modem
LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := tools/ipc-modem.c
+LOCAL_SRC_FILES := \
+ tools/ipc-modem/ipc-modem.c \
+ tools/ipc-modem/ipc-modem-log.c
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/tools/include/glibc
LOCAL_SHARED_LIBRARIES := libsamsung-ipc
include $(BUILD_EXECUTABLE)
+#########################
+# ipc-modem-static tool #
+#########################
+include $(CLEAR_VARS)
+include $(LOCAL_PATH)/android_versions.mk
+
+LOCAL_MODULE := ipc-modem-static
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ tools/ipc-modem/ipc-modem.c \
+ tools/ipc-modem/ipc-modem-log.c
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/tools/include/glibc
+LOCAL_STATIC_LIBRARIES := libsamsung-ipc
+LOCAL_SHARED_LIBRARIES := $(libsamsung_ipc_local_shared_libraries)
+
+include $(BUILD_EXECUTABLE)
+
#################
# ipc-test tool #
#################
@@ -219,7 +259,7 @@ LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := tools/nv_data-md5.c
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/tools/include/glibc
LOCAL_SHARED_LIBRARIES := libsamsung-ipc
diff --git a/CONTRIBUTING b/CONTRIBUTING
index f032039..8f9e7a1 100644
--- a/CONTRIBUTING
+++ b/CONTRIBUTING
@@ -7,7 +7,7 @@ https://git.replicant.us/replicant/hardware_replicant_libsamsung-ipc
Policies
--------
While at the time of writing, Replicant is the main user of libsamsung-ipc, and
-maintain it, libsamsung-ipc usage is not limited to Replicant nor Android.
+maintains it, libsamsung-ipc usage is not limited to Replicant nor Android.
In the past, libsamsung-ipc was used in the SHR GNU/Linux distribution
as well, with the freesmartphone.org middleware.
diff --git a/Makefile.am b/Makefile.am
index 45669d8..376f52e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,18 +1,27 @@
NULL =
+EXTRA_DIST = $(NULL)
+
SUBDIRS = \
samsung-ipc \
samsung-ipc/tests \
include \
tools \
+ tools/ipc-modem \
$(NULL)
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = samsung-ipc.pc
-EXTRA_DIST = \
+EXTRA_DIST += \
+ Android.mk \
+ android_versions.mk \
+ CONTRIBUTING \
+ INSTALL \
MAINTAINERS \
samsung-ipc.pc \
+ strict-cflags.sh \
+ tools/include/glibc/sysexits.h \
$(NULL)
MAINTAINERCLEANFILES = \
@@ -21,3 +30,75 @@ MAINTAINERCLEANFILES = \
Makefile.in missing config.h.in \
mkinstalldirs *~ \
$(NULL)
+
+################################################################################
+# Extra checks #
+################################################################################
+
+if WANT_CODE_COVERAGE
+check-local: build-code-coverage check-tarball-builds
+install-data-local: install-code-coverage
+clean-local: clean-code-coverage
+else # WANT_CODE_COVERAGE
+check-local: check-tarball-builds
+endif # WANT_CODE_COVERAGE
+
+# With the next release of libsamsung-ipc, we will also release
+# tarballs.
+#
+# Until now, no automatic testing was done with the libsamsung-ipc
+# tarballs (all tests were done with the libsamsung-ipc git
+# repository).
+#
+# We also need to verify that everything also builds and that the
+# tests also work with tarballs. This can spot mistakes where people
+# add new files that are not automatically picked up by automake and
+# forget to add these files to EXTRA_DIST.
+#
+# This test runs only from git because it is not necessary with a
+# tarball build. If we wanted to run it anyway we would end up in an
+# infinite recursion as a given test from a tarball would then spawn
+# another build and test from a tarball which would then spawn again
+# another build and test.
+check-tarball-builds: dist
+ if [ -d $(srcdir)/.git ] ; then \
+ BUILD_TMPDIR=`mktemp -d` && \
+ echo $$BUILD_TMPDIR && \
+ mkdir $$BUILD_TMPDIR/build $$BUILD_TMPDIR/destdir && \
+ tar xf $(srcdir)/libsamsung-ipc-$(VERSION).tar.xz \
+ -C $$BUILD_TMPDIR && \
+ cd $$BUILD_TMPDIR/build && \
+ ../libsamsung-ipc-$(VERSION)/configure \
+ $(CONFIGURE_ARGUMENTS) && \
+ make check && \
+ make install DESTDIR=`realpath $$BUILD_TMPDIR/destdir` && \
+ rm -rf $$BUILD_TMPDIR ; \
+ fi
+
+#################
+# Code coverage #
+#################
+if WANT_CODE_COVERAGE
+
+CODE_COVERAGE_DIR = lcov
+
+EXTRA_DIST += $(CODE_COVERAGE_DIR)
+
+build-code-coverage:
+ lcov \
+ --capture \
+ --compat-libtool \
+ --directory . \
+ --output-file libsamsung-ipc.info
+ genhtml -o $(CODE_COVERAGE_DIR) libsamsung-ipc.info
+
+install-code-coverage: check
+ install -d $(DESTDIR)/$(datadir)/libsamsung-ipc/$(CODE_COVERAGE_DIR)/
+ find $(srcdir)/$(CODE_COVERAGE_DIR) -type f | \
+ xargs -I src install -D src \
+ $(DESTDIR)/$(datadir)/libsamsung-ipc/$(CODE_COVERAGE_DIR)/
+
+clean-code-coverage:
+ rm -rf $(CODE_COVERAGE_DIR)
+
+endif # WANT_CODE_COVERAGE
diff --git a/README b/README
index 71d3331..0fb4bef 100644
--- a/README
+++ b/README
@@ -7,10 +7,11 @@ found in many Samsung devices.
Compilation and installation
============================
-In orderto compile the source code you need the following software packages
+In order to compile the source code you need the following software packages
- GCC compiler
- GNC C library
- OpenSSL >= 1.0.0e
+- curl >= 7.62.0
To configure run
./configure --prefix=/usr
diff --git a/configure.ac b/configure.ac
index d59ef0f..501a386 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,21 +1,16 @@
-AC_INIT([libsamsung-ipc], [0.6.0], [replicant@osuosl.org], [libsamsung-ipc])
+AC_INIT([libsamsung-ipc], [0.7.0], [replicant@osuosl.org], [libsamsung-ipc])
+
+AC_SUBST(CONFIGURE_ARGUMENTS)
+: ${CONFIGURE_ARGUMENTS="$@"}
+
AC_CONFIG_SRCDIR([Makefile.am])
AC_CONFIG_HEADERS(config.h)
AM_INIT_AUTOMAKE([dist-bzip2 dist-xz subdir-objects])
XZ_OPT=-v9e
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
-AC_PROG_CC
-AM_PROG_CC_C_O
-AC_GNU_SOURCE
-AC_DISABLE_STATIC
-AC_PROG_LIBTOOL
-
-AC_SUBST(CFLAGS)
-AC_SUBST(CPPFLAGS)
-AC_SUBST(LDFLAGS)
-
OPENSSL_REQUIRED=1.0.0e
+LIBCURL_REQUIRED=7.62.0
#------------------------------------------------------------------------------
# pkg-config
@@ -30,15 +25,113 @@ AC_SUBST(OPENSSL_CFLAGS)
AC_SUBST(OPENSSL_LIBS)
#------------------------------------------------------------------------------
+# strict cflags
+AC_SUBST(STRICT_CFLAGS)
+
+#------------------------------------------------------------------------------
+# Static build of test utilities
+AC_SUBST(ALL_STATIC_LDFLAGS)
+
+#------------------------------------------------------------------------------
+# python
+AC_SUBST(PYTHON3)
+AC_CHECK_PROG([PYTHON3], [python3], [python3])
+#------------------------------------------------------------------------------
+# code coverage
+AC_SUBST(CODE_COVERAGE)
+#------------------------------------------------------------------------------
+# valgrind
+AC_SUBST(VALGRIND)
+
+#------------------------------------------------------------------------------
+# ipc device name
+AC_SUBST([IPC_DEVICE_NAME], [all])
+
+#------------------------------------------------------------------------------
+# libcurl
+PKG_CHECK_MODULES(LIBCURL, libcurl >= $LIBCURL_REQUIRED)
+AC_SUBST(LIBCURL_CFLAGS)
+AC_SUBST(LIBCURL_LIBS)
+
+#------------------------------------------------------------------------------
# check for debugging
AC_ARG_ENABLE(debug,
- [ --enable-debug Enable debug build (default=disabled)],
+ [AS_HELP_STRING([--enable-debug], [Enable debug build (default=disabled)])],
[debug=$enableval],
[debug="no"])
AM_CONDITIONAL( [WANT_DEBUG], [test x"$debug" = x"yes"])
#------------------------------------------------------------------------------
+AC_ARG_ENABLE(static-progs,
+ [AS_HELP_STRING([--enable-static-progs],
+ [Build static (test) tools (default=disabled)])],
+ [static_progs=$enableval],
+ [static_progs="no"])
+
+#------------------------------------------------------------------------------
+AC_ARG_ENABLE(strict-cflags,
+ [AS_HELP_STRING([--enable-strict-cflags],
+ [Build with strict cflags (default=disabled)])],
+ [strict_cflags=$enableval],
+ [strict_cflags="no"])
+AM_CONDITIONAL( [WANT_STRICT_CFLAGS], [test x"$strict_cflags" = x"yes"])
+
+#------------------------------------------------------------------------------
+# TODO: GCC has --enable-checking= for extensive runtime checks and one of the
+# available values is valgrind, so it would be a good idea to convert to
+# it for consistency across free software projects.
+AC_ARG_ENABLE(
+ [code-coverage-tests],
+ [AS_HELP_STRING([--enable-code-coverage-tests],
+ [Build with --coverage, -O0 and use lcov from PATH during
+ tests (default=disabled)])],
+ [code_coverage_tests=$enableval],
+ [code_coverage="no"])
+
+AM_CONDITIONAL( [WANT_CODE_COVERAGE], [test x"$code_coverage_tests" = x"yes"])
+
+AS_IF([test x"$code_coverage_tests" = x"yes"],
+ [AC_CHECK_PROG([CODE_COVERAGE], [lcov], [lcov])
+ AS_IF(
+ [test x"$CODE_COVERAGE" = x""],
+ [AC_MSG_ERROR(
+ [code coverage tests are enabled but lcov was not found in PATH ($PATH)])])])
+
+#------------------------------------------------------------------------------
+# TODO: GCC has --enable-checking= for extensive runtime checks and one of the
+# available values is valgrind, so it would be a good idea to convert to
+# it for consistency across free software projects.
+AC_ARG_ENABLE(
+ [valgrind-tests],
+ [AS_HELP_STRING([--enable-valgrind-tests],
+ [Build with -ggdb3, -O0 and use valgrind from PATH during
+ tests (default=disabled)])],
+ [valgrind_tests=$enableval],
+ [valgrind_tests="no"])
+
+AM_CONDITIONAL( [WANT_VALGRIND_CHECKING], [test x"$valgrind_tests" = x"yes"])
+
+AS_IF([test x"$valgrind_tests" = x"yes"],
+ [AC_CHECK_PROG([VALGRIND], [valgrind], [valgrind])
+ AS_IF(
+ [test x"$VALGRIND" = x""],
+ [AC_MSG_ERROR(
+ [valgrind tests are enabled but valgrind was not found in PATH ($PATH)])])])
+#------------------------------------------------------------------------------
+AC_ARG_ENABLE(samsung-ipc-device,
+ [ --enable-samsung-ipc-device=[DEVICE]
+ make libsamsung-ipc assumes that it runs on DEVICE
+ DEVICE={all,aries,crespo,galaxys2,herolte,i9300,maguro,n5100,n7100,piranha} (default=all)],
+ [AS_CASE([$enableval],
+ [aries|crespo|galaxys2|herolte|i9300|maguro|n5100|n7100|piranha],
+ [IPC_DEVICE_NAME=$enableval],
+ [AC_MSG_ERROR([Unknown device $enableval])])],
+ [IPC_DEVICE_NAME="all"])
+
+AM_CONDITIONAL( [WANT_IPC_DEVICE_NAME], [test x"$IPC_DEVICE_NAME" != x"all"])
+#------------------------------------------------------------------------------
+
AC_CONFIG_FILES([
Makefile
samsung-ipc.pc
@@ -46,23 +139,67 @@ AC_CONFIG_FILES([
samsung-ipc/Makefile
samsung-ipc/tests/Makefile
tools/Makefile
+ tools/ipc-modem/Makefile
])
-AC_OUTPUT
+
#------------------------------------------------------------------------------
+AS_IF([test x"$static_progs" = x"yes"],
+ [ALL_STATIC_LDFLAGS=-all-static], [])
+
+AS_IF([test x"$strict_cflags" = x"yes"],
+ [STRICT_CFLAGS=`$srcdir/strict-cflags.sh`], [])
+
+AS_IF([test x"$valgrind_tests" = x"yes"], [: ${CFLAGS="-ggdb3 -O0"}],
+ [test x"$debug" = x"yes"], [: ${CFLAGS="-ggdb -O0"}], [])
+
+AS_IF([test x"$code_coverage_tests" = x"yes"],
+ [: ${LDFLAGS=" --coverage"}], [])
+
+AS_IF([test x"$code_coverage_tests" = x"yes"],
+ [ CFLAGS+=" --coverage"], [])
+
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_GNU_SOURCE
+AC_DISABLE_STATIC
+AC_PROG_LIBTOOL
+
+AC_SUBST(CFLAGS)
+AC_SUBST(CPPFLAGS)
+AC_SUBST(LDFLAGS)
+AC_SUBST(ALL_STATIC_LDFLAGS)
+
+AC_OUTPUT
+#------------------------------------------------------------------------------
# info
echo "------------------------------------------------------------------------"
echo "$PACKAGE_NAME $PACKAGE_VERSION"
echo "------------------------------------------------------------------------"
echo
+echo "Compiler flags:"
+echo
+echo " CFLAGS..................: $CFLAGS $STRICT_CFLAGS"
+echo " LDFLAGS.................: $LDFLAGS $ALL_STATIC_LDFLAGS"
+echo
+echo
+echo "Interpreters paths:"
+echo
+echo " PYTHON3..................: $PYTHON3"
+echo
+echo
echo "Configuration Options:"
echo
echo " debug build.............: $debug"
echo
+echo " device(s)...............: $IPC_DEVICE_NAME"
+echo
echo " prefix..................: $prefix"
echo
+echo " valgrind tests..........: $valgrind_tests"
+echo
+echo " code coverage tests.....: $code_coverage_tests"
echo "------------------------------------------------------------------------"
echo
echo "Now type 'make' to compile and 'make install' to install this package."
-
diff --git a/include/samsung-ipc.h b/include/samsung-ipc.h
index 53f1f72..d9aa7c7 100644
--- a/include/samsung-ipc.h
+++ b/include/samsung-ipc.h
@@ -138,6 +138,7 @@ const char *ipc_request_type_string(unsigned char type);
const char *ipc_response_type_string(unsigned char type);
const char *ipc_command_string(unsigned short command);
const char *ipc_group_string(unsigned char group);
+const char *ipc_client_type_string(unsigned char client_type);
int ipc_data_dump(struct ipc_client *client, const void *data, size_t size);
void ipc_client_log_send(struct ipc_client *client, struct ipc_message *message,
diff --git a/samsung-ipc/Makefile.am b/samsung-ipc/Makefile.am
index ed6331f..47484e5 100644
--- a/samsung-ipc/Makefile.am
+++ b/samsung-ipc/Makefile.am
@@ -6,8 +6,16 @@ AM_CFLAGS = \
$(OPENSSL_CFLAGS) \
$(NULL)
+if WANT_STRICT_CFLAGS
+AM_CFLAGS += $(STRICT_CFLAGS)
+endif
+
if WANT_DEBUG
-AM_CFLAGS += -ggdb -O0 -DDEBUG
+AM_CFLAGS += -DDEBUG
+endif
+
+if WANT_IPC_DEVICE_NAME
+AM_CFLAGS += -DIPC_DEVICE_NAME=\"$(IPC_DEVICE_NAME)\"
endif
lib_LTLIBRARIES = \
@@ -17,6 +25,7 @@ lib_LTLIBRARIES = \
libsamsung_ipc_la_SOURCES = \
ipc.c \
ipc.h \
+ ipc_strings.c \
ipc_utils.c \
utils.c \
call.c \
diff --git a/samsung-ipc/devices/aries/aries.c b/samsung-ipc/devices/aries/aries.c
index 93d5d31..9fc905a 100644
--- a/samsung-ipc/devices/aries/aries.c
+++ b/samsung-ipc/devices/aries/aries.c
@@ -819,11 +819,16 @@ char *aries_gprs_get_iface(__attribute__((unused)) struct ipc_client *client,
unsigned int cid)
{
char *iface = NULL;
+ int rc;
if (cid > ARIES_GPRS_IFACE_COUNT)
return NULL;
- asprintf(&iface, "%s%d", ARIES_GPRS_IFACE_PREFIX, cid - 1);
+ rc = asprintf(&iface, "%s%d", ARIES_GPRS_IFACE_PREFIX, cid - 1);
+ if (rc == -1) {
+ ipc_client_log(client, "%s: asprintf failed", __func__);
+ return NULL;
+ }
return iface;
}
diff --git a/samsung-ipc/devices/crespo/crespo.c b/samsung-ipc/devices/crespo/crespo.c
index ebb6075..5399e77 100644
--- a/samsung-ipc/devices/crespo/crespo.c
+++ b/samsung-ipc/devices/crespo/crespo.c
@@ -553,13 +553,17 @@ int crespo_gprs_deactivate(__attribute__((unused)) struct ipc_client *client,
return 0;
}
-char *crespo_gprs_get_iface_single(
- __attribute__((unused)) struct ipc_client *client,
- __attribute__((unused)) unsigned int cid)
+char *crespo_gprs_get_iface_single(struct ipc_client *client,
+ __attribute__((unused)) unsigned int cid)
{
char *iface = NULL;
+ int rc;
- asprintf(&iface, "%s%d", CRESPO_GPRS_IFACE_PREFIX, 0);
+ rc = asprintf(&iface, "%s%d", CRESPO_GPRS_IFACE_PREFIX, 0);
+ if (rc == -1) {
+ ipc_client_log(client, "%s: asprintf failed", __func__);
+ return NULL;
+ }
return iface;
}
@@ -580,11 +584,16 @@ char *crespo_gprs_get_iface(__attribute__((unused)) struct ipc_client *client,
unsigned int cid)
{
char *iface = NULL;
+ int rc;
if (cid > CRESPO_GPRS_IFACE_COUNT)
return NULL;
- asprintf(&iface, "%s%d", CRESPO_GPRS_IFACE_PREFIX, cid - 1);
+ rc = asprintf(&iface, "%s%d", CRESPO_GPRS_IFACE_PREFIX, cid - 1);
+ if (rc == -1) {
+ ipc_client_log(client, "%s: asprintf failed", __func__);
+ return NULL;
+ }
return iface;
}
diff --git a/samsung-ipc/gprs.c b/samsung-ipc/gprs.c
index 89f06e7..c9722e5 100644
--- a/samsung-ipc/gprs.c
+++ b/samsung-ipc/gprs.c
@@ -35,7 +35,7 @@ int ipc_gprs_define_pdp_context_setup(
data->cid = cid;
data->magic = 0x02;
- strncpy((char *) data->apn, apn, sizeof(data->apn));
+ memcpy(data->apn, apn, sizeof(data->apn));
return 0;
}
@@ -56,9 +56,9 @@ int ipc_gprs_pdp_context_request_set_setup(
data->magic1[2] = 0x13;
data->magic2 = 0x01;
- strncpy((char *) data->username, username,
+ memcpy(data->username, username,
sizeof(data->username));
- strncpy((char *) data->password, password,
+ memcpy(data->password, password,
sizeof(data->password));
}
diff --git a/samsung-ipc/ipc_strings.c b/samsung-ipc/ipc_strings.c
new file mode 100644
index 0000000..e7e6e8b
--- /dev/null
+++ b/samsung-ipc/ipc_strings.c
@@ -0,0 +1,409 @@
+/*
+ * This file is part of libsamsung-ipc.
+ *
+ * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com>
+ * Copyright (C) 2013-2014 Paul Kocialkowski <contact@paulk.fr>
+ *
+ * libsamsung-ipc 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libsamsung-ipc 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 libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+
+#include <samsung-ipc.h>
+
+const char *ipc_request_type_string(unsigned char type)
+{
+ static char type_string[5] = { 0 };
+
+ switch (type) {
+ case IPC_TYPE_EXEC:
+ return "IPC_TYPE_EXEC";
+ case IPC_TYPE_GET:
+ return "IPC_TYPE_GET";
+ case IPC_TYPE_SET:
+ return "IPC_TYPE_SET";
+ case IPC_TYPE_CFRM:
+ return "IPC_TYPE_CFRM";
+ case IPC_TYPE_EVENT:
+ return "IPC_TYPE_EVENT";
+ default:
+ snprintf((char *) &type_string, sizeof(type_string), "0x%02x",
+ type);
+ return type_string;
+ }
+}
+
+const char *ipc_response_type_string(unsigned char type)
+{
+ static char type_string[5] = { 0 };
+
+ switch (type) {
+ case IPC_TYPE_INDI:
+ return "IPC_TYPE_INDI";
+ case IPC_TYPE_RESP:
+ return "IPC_TYPE_RESP";
+ case IPC_TYPE_NOTI:
+ return "IPC_TYPE_NOTI";
+ default:
+ snprintf((char *) &type_string, sizeof(type_string), "0x%02x",
+ type);
+ return type_string;
+ }
+}
+
+const char *ipc_command_string(unsigned short command)
+{
+ static char command_string[7] = { 0 };
+
+ switch (command) {
+ case IPC_PWR_PHONE_PWR_UP:
+ return "IPC_PWR_PHONE_PWR_UP";
+ case IPC_PWR_PHONE_PWR_OFF:
+ return "IPC_PWR_PHONE_PWR_OFF";
+ case IPC_PWR_PHONE_RESET:
+ return "IPC_PWR_PHONE_RESET";
+ case IPC_PWR_BATT_STATUS:
+ return "IPC_PWR_BATT_STATUS";
+ case IPC_PWR_BATT_TYPE:
+ return "IPC_PWR_BATT_TYPE";
+ case IPC_PWR_BATT_COMP:
+ return "IPC_PWR_BATT_COMP";
+ case IPC_PWR_PHONE_STATE:
+ return "IPC_PWR_PHONE_STATE";
+ case IPC_CALL_OUTGOING:
+ return "IPC_CALL_OUTGOING";
+ case IPC_CALL_INCOMING:
+ return "IPC_CALL_INCOMING";
+ case IPC_CALL_RELEASE:
+ return "IPC_CALL_RELEASE";
+ case IPC_CALL_ANSWER:
+ return "IPC_CALL_ANSWER";
+ case IPC_CALL_STATUS:
+ return "IPC_CALL_STATUS";
+ case IPC_CALL_LIST:
+ return "IPC_CALL_LIST";
+ case IPC_CALL_BURST_DTMF:
+ return "IPC_CALL_BURST_DTMF";
+ case IPC_CALL_CONT_DTMF:
+ return "IPC_CALL_CONT_DTMF";
+ case IPC_CALL_WAITING:
+ return "IPC_CALL_WAITING";
+ case IPC_CALL_LINE_ID:
+ return "IPC_CALL_LINE_ID";
+ case IPC_SMS_SEND_MSG:
+ return "IPC_SMS_SEND_MSG";
+ case IPC_SMS_INCOMING_MSG:
+ return "IPC_SMS_INCOMING_MSG";
+ case IPC_SMS_READ_MSG:
+ return "IPC_SMS_READ_MSG";
+ case IPC_SMS_SAVE_MSG:
+ return "IPC_SMS_SAVE_MSG";
+ case IPC_SMS_DEL_MSG:
+ return "IPC_SMS_DEL_MSG";
+ case IPC_SMS_DELIVER_REPORT:
+ return "IPC_SMS_DELIVER_REPORT";
+ case IPC_SMS_DEVICE_READY:
+ return "IPC_SMS_DEVICE_READY";
+ case IPC_SMS_SEL_MEM:
+ return "IPC_SMS_SEL_MEM";
+ case IPC_SMS_STORED_MSG_COUNT:
+ return "IPC_SMS_STORED_MSG_COUNT";
+ case IPC_SMS_SVC_CENTER_ADDR:
+ return "IPC_SMS_SVC_CENTER_ADDR";
+ case IPC_SMS_SVC_OPTION:
+ return "IPC_SMS_SVC_OPTION";
+ case IPC_SMS_MEM_STATUS:
+ return "IPC_SMS_MEM_STATUS";
+ case IPC_SMS_CBS_MSG:
+ return "IPC_SMS_CBS_MSG";
+ case IPC_SMS_CBS_CFG:
+ return "IPC_SMS_CBS_CFG";
+ case IPC_SMS_STORED_MSG_STATUS:
+ return "IPC_SMS_STORED_MSG_STATUS";
+ case IPC_SMS_PARAM_COUNT:
+ return "IPC_SMS_PARAM_COUNT";
+ case IPC_SMS_PARAM:
+ return "IPC_SMS_PARAM";
+ case IPC_SEC_PIN_STATUS:
+ return "IPC_SEC_PIN_STATUS";
+ case IPC_SEC_PHONE_LOCK:
+ return "IPC_SEC_PHONE_LOCK";
+ case IPC_SEC_CHANGE_LOCKING_PW:
+ return "IPC_SEC_CHANGE_LOCKING_PW";
+ case IPC_SEC_SIM_LANG:
+ return "IPC_SEC_SIM_LANG";
+ case IPC_SEC_RSIM_ACCESS:
+ return "IPC_SEC_RSIM_ACCESS";
+ case IPC_SEC_GSIM_ACCESS:
+ return "IPC_SEC_GSIM_ACCESS";
+ case IPC_SEC_SIM_ICC_TYPE:
+ return "IPC_SEC_SIM_ICC_TYPE";
+ case IPC_SEC_LOCK_INFORMATION:
+ return "IPC_SEC_LOCK_INFORMATION";
+ case IPC_SEC_IMS_AUTH:
+ return "IPC_SEC_IMS_AUTH";
+ case IPC_PB_ACCESS:
+ return "IPC_PB_ACCESS";
+ case IPC_PB_STORAGE:
+ return "IPC_PB_STORAGE";
+ case IPC_PB_STORAGE_LIST:
+ return "IPC_PB_STORAGE_LIST";
+ case IPC_PB_ENTRY_INFO:
+ return "IPC_PB_ENTRY_INFO";
+ case IPC_PB_3GPB_CAPA:
+ return "IPC_PB_3GPB_CAPA";
+ case IPC_DISP_ICON_INFO:
+ return "IPC_DISP_ICON_INFO";
+ case IPC_DISP_HOMEZONE_INFO:
+ return "IPC_DISP_HOMEZONE_INFO";
+ case IPC_DISP_RSSI_INFO:
+ return "IPC_DISP_RSSI_INFO";
+ case IPC_NET_PREF_PLMN:
+ return "IPC_NET_PREF_PLMN";
+ case IPC_NET_PLMN_SEL:
+ return "IPC_NET_PLMN_SEL";
+ case IPC_NET_SERVING_NETWORK:
+ return "IPC_NET_SERVING_NETWORK";
+ case IPC_NET_PLMN_LIST:
+ return "IPC_NET_PLMN_LIST";
+ case IPC_NET_REGIST:
+ return "IPC_NET_REGIST";
+ case IPC_NET_SUBSCRIBER_NUM:
+ return "IPC_NET_SUBSCRIBER_NUM";
+ case IPC_NET_BAND_SEL:
+ return "IPC_NET_BAND_SEL";
+ case IPC_NET_SERVICE_DOMAIN_CONFIG:
+ return "IPC_NET_SERVICE_DOMAIN_CONFIG";
+ case IPC_NET_POWERON_ATTACH:
+ return "IPC_NET_POWERON_ATTACH";
+ case IPC_NET_MODE_SEL:
+ return "IPC_NET_MODE_SEL";
+ case IPC_NET_ACQ_ORDER:
+ return "IPC_NET_ACQ_ORDER";
+ case IPC_NET_IDENTITY:
+ return "IPC_NET_IDENTITY";
+ case IPC_NET_PREFERRED_NETWORK_INFO:
+ return "IPC_NET_PREFERRED_NETWORK_INFO";
+ case IPC_SND_SPKR_VOLUME_CTRL:
+ return "IPC_SND_SPKR_VOLUME_CTRL";
+ case IPC_SND_MIC_MUTE_CTRL:
+ return "IPC_SND_MIC_MUTE_CTRL";
+ case IPC_SND_AUDIO_PATH_CTRL:
+ return "IPC_SND_AUDIO_PATH_CTRL";
+ case IPC_SND_AUDIO_SOURCE_CTRL:
+ return "IPC_SND_AUDIO_SOURCE_CTRL";
+ case IPC_SND_LOOPBACK_CTRL:
+ return "IPC_SND_LOOPBACK_CTRL";
+ case IPC_SND_VOICE_RECORDING_CTRL:
+ return "IPC_SND_VOICE_RECORDING_CTRL";
+ case IPC_SND_VIDEO_CALL_CTRL:
+ return "IPC_SND_VIDEO_CALL_CTRL";
+ case IPC_SND_RINGBACK_TONE_CTRL:
+ return "IPC_SND_RINGBACK_TONE_CTRL";
+ case IPC_SND_CLOCK_CTRL:
+ return "IPC_SND_CLOCK_CTRL";
+ case IPC_SND_WB_AMR_STATUS:
+ return "IPC_SND_WB_AMR_STATUS";
+ case IPC_MISC_ME_VERSION:
+ return "IPC_MISC_ME_VERSION";
+ case IPC_MISC_ME_IMSI:
+ return "IPC_MISC_ME_IMSI";
+ case IPC_MISC_ME_SN:
+ return "IPC_MISC_ME_SN";
+ case IPC_MISC_TIME_INFO:
+ return "IPC_MISC_TIME_INFO";
+ case IPC_MISC_DEBUG_LEVEL:
+ return "IPC_MISC_DEBUG_LEVEL";
+ case IPC_SVC_ENTER:
+ return "IPC_SVC_ENTER";
+ case IPC_SVC_END:
+ return "IPC_SVC_END";
+ case IPC_SVC_PRO_KEYCODE:
+ return "IPC_SVC_PRO_KEYCODE";
+ case IPC_SVC_SCREEN_CFG:
+ return "IPC_SVC_SCREEN_CFG";
+ case IPC_SVC_DISPLAY_SCREEN:
+ return "IPC_SVC_DISPLAY_SCREEN";
+ case IPC_SVC_CHANGE_SVC_MODE:
+ return "IPC_SVC_CHANGE_SVC_MODE";
+ case IPC_SVC_DEVICE_TEST:
+ return "IPC_SVC_DEVICE_TEST";
+ case IPC_SVC_DEBUG_DUMP:
+ return "IPC_SVC_DEBUG_DUMP";
+ case IPC_SVC_DEBUG_STRING:
+ return "IPC_SVC_DEBUG_STRING";
+ case IPC_SS_WAITING:
+ return "IPC_SS_WAITING";
+ case IPC_SS_CLI:
+ return "IPC_SS_CLI";
+ case IPC_SS_BARRING:
+ return "IPC_SS_BARRING";
+ case IPC_SS_BARRING_PW:
+ return "IPC_SS_BARRING_PW";
+ case IPC_SS_FORWARDING:
+ return "IPC_SS_FORWARDING";
+ case IPC_SS_INFO:
+ return "IPC_SS_INFO";
+ case IPC_SS_MANAGE_CALL:
+ return "IPC_SS_MANAGE_CALL";
+ case IPC_SS_USSD:
+ return "IPC_SS_USSD";
+ case IPC_SS_AOC:
+ return "IPC_SS_AOC";
+ case IPC_SS_RELEASE_COMPLETE:
+ return "IPC_SS_RELEASE_COMPLETE";
+ case IPC_GPRS_DEFINE_PDP_CONTEXT:
+ return "IPC_GPRS_DEFINE_PDP_CONTEXT";
+ case IPC_GPRS_QOS:
+ return "IPC_GPRS_QOS";
+ case IPC_GPRS_PS:
+ return "IPC_GPRS_PS";
+ case IPC_GPRS_PDP_CONTEXT:
+ return "IPC_GPRS_PDP_CONTEXT";
+ case IPC_GPRS_ENTER_DATA:
+ return "IPC_GPRS_ENTER_DATA";
+ case IPC_GPRS_SHOW_PDP_ADDR:
+ return "IPC_GPRS_SHOW_PDP_ADDR";
+ case IPC_GPRS_MS_CLASS:
+ return "IPC_GPRS_MS_CLASS";
+ case IPC_GPRS_3G_QUAL_SRVC_PROFILE:
+ return "IPC_GPRS_3G_QUAL_SRVC_PROFILE";
+ case IPC_GPRS_IP_CONFIGURATION:
+ return "IPC_GPRS_IP_CONFIGURATION";
+ case IPC_GPRS_DEFINE_SEC_PDP_CONTEXT:
+ return "IPC_GPRS_DEFINE_SEC_PDP_CONTEXT";
+ case IPC_GPRS_TFT:
+ return "IPC_GPRS_TFT";
+ case IPC_GPRS_HSDPA_STATUS:
+ return "IPC_GPRS_HSDPA_STATUS";
+ case IPC_GPRS_CURRENT_SESSION_DATA_COUNTER:
+ return "IPC_GPRS_CURRENT_SESSION_DATA_COUNTER";
+ case IPC_GPRS_DATA_DORMANT:
+ return "IPC_GPRS_DATA_DORMANT";
+ case IPC_GPRS_PIN_CTRL:
+ return "IPC_GPRS_PIN_CTRL";
+ case IPC_GPRS_CALL_STATUS:
+ return "IPC_GPRS_CALL_STATUS";
+ case IPC_GPRS_PORT_LIST:
+ return "IPC_GPRS_PORT_LIST";
+ case IPC_SAT_PROFILE_DOWNLOAD:
+ return "IPC_SAT_PROFILE_DOWNLOAD";
+ case IPC_SAT_ENVELOPE_CMD:
+ return "IPC_SAT_ENVELOPE_CMD";
+ case IPC_SAT_PROACTIVE_CMD:
+ return "IPC_SAT_PROACTIVE_CMD";
+ case IPC_SAT_TERMINATE_USAT_SESSION:
+ return "IPC_SAT_TERMINATE_USAT_SESSION";
+ case IPC_SAT_EVENT_DOWNLOAD:
+ return "IPC_SAT_EVENT_DOWNLOAD";
+ case IPC_SAT_PROVIDE_LOCAL_INFO:
+ return "IPC_SAT_PROVIDE_LOCAL_INFO";
+ case IPC_SAT_POLLING:
+ return "IPC_SAT_POLLING";
+ case IPC_SAT_REFRESH:
+ return "IPC_SAT_REFRESH";
+ case IPC_SAT_SETUP_EVENT_LIST:
+ return "IPC_SAT_SETUP_EVENT_LIST";
+ case IPC_SAT_CALL_CONTROL_RESULT:
+ return "IPC_SAT_CALL_CONTROL_RESULT";
+ case IPC_SAT_IMAGE_CLUT:
+ return "IPC_SAT_IMAGE_CLUT";
+ case IPC_SAT_SETUP_CALL_PROCESSING:
+ return "IPC_SAT_SETUP_CALL_PROCESSING";
+ case IPC_IMEI_START:
+ return "IPC_IMEI_START";
+ case IPC_IMEI_CHECK_DEVICE_INFO:
+ return "IPC_IMEI_CHECK_DEVICE_INFO";
+ case IPC_RFS_NV_READ_ITEM:
+ return "IPC_RFS_NV_READ_ITEM";
+ case IPC_RFS_NV_WRITE_ITEM:
+ return "IPC_RFS_NV_WRITE_ITEM";
+ case IPC_GEN_PHONE_RES:
+ return "IPC_GEN_PHONE_RES";
+ default:
+ snprintf((char *) &command_string, sizeof(command_string),
+ "0x%04x", command);
+ return command_string;
+ }
+}
+
+const char *ipc_group_string(unsigned char group)
+{
+ static char group_string[5] = { 0 };
+
+ switch (group) {
+ case IPC_GROUP_PWR:
+ return "IPC_GROUP_PWR";
+ case IPC_GROUP_CALL:
+ return "IPC_GROUP_CALL";
+ case IPC_GROUP_SMS:
+ return "IPC_GROUP_SMS";
+ case IPC_GROUP_SEC:
+ return "IPC_GROUP_SEC";
+ case IPC_GROUP_PB:
+ return "IPC_GROUP_PB";
+ case IPC_GROUP_DISP:
+ return "IPC_GROUP_DISP";
+ case IPC_GROUP_NET:
+ return "IPC_GROUP_NET";
+ case IPC_GROUP_SND:
+ return "IPC_GROUP_SND";
+ case IPC_GROUP_MISC:
+ return "IPC_GROUP_MISC";
+ case IPC_GROUP_SVC:
+ return "IPC_GROUP_SVC";
+ case IPC_GROUP_SS:
+ return "IPC_GROUP_SS";
+ case IPC_GROUP_GPRS:
+ return "IPC_GROUP_GPRS";
+ case IPC_GROUP_SAT:
+ return "IPC_GROUP_SAT";
+ case IPC_GROUP_CFG:
+ return "IPC_GROUP_CFG";
+ case IPC_GROUP_IMEI:
+ return "IPC_GROUP_IMEI";
+ case IPC_GROUP_GPS:
+ return "IPC_GROUP_GPS";
+ case IPC_GROUP_SAP:
+ return "IPC_GROUP_SAP";
+ case IPC_GROUP_RFS:
+ return "IPC_GROUP_RFS";
+ case IPC_GROUP_GEN:
+ return "IPC_GROUP_GEN";
+ default:
+ snprintf((char *) &group_string, sizeof(group_string), "0x%02x",
+ (unsigned int)group);
+ return group_string;
+ }
+}
+
+const char *ipc_client_type_string(unsigned char client_type)
+{
+ static char client_type_string[5] = { 0 };
+
+ switch (client_type) {
+ case IPC_CLIENT_TYPE_FMT:
+ return "FMT";
+ case IPC_CLIENT_TYPE_RFS:
+ return "RFS";
+ case IPC_CLIENT_TYPE_DUMMY:
+ return "DUMMY";
+ default:
+ snprintf((char *) &client_type_string,
+ sizeof(client_type_string),
+ "0x%02x",
+ client_type);
+ return client_type_string;
+ }
+}
diff --git a/samsung-ipc/ipc_utils.c b/samsung-ipc/ipc_utils.c
index 9c4ccb8..3518475 100644
--- a/samsung-ipc/ipc_utils.c
+++ b/samsung-ipc/ipc_utils.c
@@ -41,372 +41,6 @@ int ipc_seq_valid(unsigned char seq)
return 1;
}
-const char *ipc_request_type_string(unsigned char type)
-{
- static char type_string[5] = { 0 };
-
- switch (type) {
- case IPC_TYPE_EXEC:
- return "IPC_TYPE_EXEC";
- case IPC_TYPE_GET:
- return "IPC_TYPE_GET";
- case IPC_TYPE_SET:
- return "IPC_TYPE_SET";
- case IPC_TYPE_CFRM:
- return "IPC_TYPE_CFRM";
- case IPC_TYPE_EVENT:
- return "IPC_TYPE_EVENT";
- default:
- snprintf((char *) &type_string, sizeof(type_string), "0x%02x",
- type);
- return type_string;
- }
-}
-
-const char *ipc_response_type_string(unsigned char type)
-{
- static char type_string[5] = { 0 };
-
- switch (type) {
- case IPC_TYPE_INDI:
- return "IPC_TYPE_INDI";
- case IPC_TYPE_RESP:
- return "IPC_TYPE_RESP";
- case IPC_TYPE_NOTI:
- return "IPC_TYPE_NOTI";
- default:
- snprintf((char *) &type_string, sizeof(type_string), "0x%02x",
- type);
- return type_string;
- }
-}
-
-const char *ipc_command_string(unsigned short command)
-{
- static char command_string[7] = { 0 };
-
- switch (command) {
- case IPC_PWR_PHONE_PWR_UP:
- return "IPC_PWR_PHONE_PWR_UP";
- case IPC_PWR_PHONE_PWR_OFF:
- return "IPC_PWR_PHONE_PWR_OFF";
- case IPC_PWR_PHONE_RESET:
- return "IPC_PWR_PHONE_RESET";
- case IPC_PWR_BATT_STATUS:
- return "IPC_PWR_BATT_STATUS";
- case IPC_PWR_BATT_TYPE:
- return "IPC_PWR_BATT_TYPE";
- case IPC_PWR_BATT_COMP:
- return "IPC_PWR_BATT_COMP";
- case IPC_PWR_PHONE_STATE:
- return "IPC_PWR_PHONE_STATE";
- case IPC_CALL_OUTGOING:
- return "IPC_CALL_OUTGOING";
- case IPC_CALL_INCOMING:
- return "IPC_CALL_INCOMING";
- case IPC_CALL_RELEASE:
- return "IPC_CALL_RELEASE";
- case IPC_CALL_ANSWER:
- return "IPC_CALL_ANSWER";
- case IPC_CALL_STATUS:
- return "IPC_CALL_STATUS";
- case IPC_CALL_LIST:
- return "IPC_CALL_LIST";
- case IPC_CALL_BURST_DTMF:
- return "IPC_CALL_BURST_DTMF";
- case IPC_CALL_CONT_DTMF:
- return "IPC_CALL_CONT_DTMF";
- case IPC_CALL_WAITING:
- return "IPC_CALL_WAITING";
- case IPC_CALL_LINE_ID:
- return "IPC_CALL_LINE_ID";
- case IPC_SMS_SEND_MSG:
- return "IPC_SMS_SEND_MSG";
- case IPC_SMS_INCOMING_MSG:
- return "IPC_SMS_INCOMING_MSG";
- case IPC_SMS_READ_MSG:
- return "IPC_SMS_READ_MSG";
- case IPC_SMS_SAVE_MSG:
- return "IPC_SMS_SAVE_MSG";
- case IPC_SMS_DEL_MSG:
- return "IPC_SMS_DEL_MSG";
- case IPC_SMS_DELIVER_REPORT:
- return "IPC_SMS_DELIVER_REPORT";
- case IPC_SMS_DEVICE_READY:
- return "IPC_SMS_DEVICE_READY";
- case IPC_SMS_SEL_MEM:
- return "IPC_SMS_SEL_MEM";
- case IPC_SMS_STORED_MSG_COUNT:
- return "IPC_SMS_STORED_MSG_COUNT";
- case IPC_SMS_SVC_CENTER_ADDR:
- return "IPC_SMS_SVC_CENTER_ADDR";
- case IPC_SMS_SVC_OPTION:
- return "IPC_SMS_SVC_OPTION";
- case IPC_SMS_MEM_STATUS:
- return "IPC_SMS_MEM_STATUS";
- case IPC_SMS_CBS_MSG:
- return "IPC_SMS_CBS_MSG";
- case IPC_SMS_CBS_CFG:
- return "IPC_SMS_CBS_CFG";
- case IPC_SMS_STORED_MSG_STATUS:
- return "IPC_SMS_STORED_MSG_STATUS";
- case IPC_SMS_PARAM_COUNT:
- return "IPC_SMS_PARAM_COUNT";
- case IPC_SMS_PARAM:
- return "IPC_SMS_PARAM";
- case IPC_SEC_PIN_STATUS:
- return "IPC_SEC_PIN_STATUS";
- case IPC_SEC_PHONE_LOCK:
- return "IPC_SEC_PHONE_LOCK";
- case IPC_SEC_CHANGE_LOCKING_PW:
- return "IPC_SEC_CHANGE_LOCKING_PW";
- case IPC_SEC_SIM_LANG:
- return "IPC_SEC_SIM_LANG";
- case IPC_SEC_RSIM_ACCESS:
- return "IPC_SEC_RSIM_ACCESS";
- case IPC_SEC_GSIM_ACCESS:
- return "IPC_SEC_GSIM_ACCESS";
- case IPC_SEC_SIM_ICC_TYPE:
- return "IPC_SEC_SIM_ICC_TYPE";
- case IPC_SEC_LOCK_INFORMATION:
- return "IPC_SEC_LOCK_INFORMATION";
- case IPC_SEC_IMS_AUTH:
- return "IPC_SEC_IMS_AUTH";
- case IPC_PB_ACCESS:
- return "IPC_PB_ACCESS";
- case IPC_PB_STORAGE:
- return "IPC_PB_STORAGE";
- case IPC_PB_STORAGE_LIST:
- return "IPC_PB_STORAGE_LIST";
- case IPC_PB_ENTRY_INFO:
- return "IPC_PB_ENTRY_INFO";
- case IPC_PB_3GPB_CAPA:
- return "IPC_PB_3GPB_CAPA";
- case IPC_DISP_ICON_INFO:
- return "IPC_DISP_ICON_INFO";
- case IPC_DISP_HOMEZONE_INFO:
- return "IPC_DISP_HOMEZONE_INFO";
- case IPC_DISP_RSSI_INFO:
- return "IPC_DISP_RSSI_INFO";
- case IPC_NET_PREF_PLMN:
- return "IPC_NET_PREF_PLMN";
- case IPC_NET_PLMN_SEL:
- return "IPC_NET_PLMN_SEL";
- case IPC_NET_SERVING_NETWORK:
- return "IPC_NET_SERVING_NETWORK";
- case IPC_NET_PLMN_LIST:
- return "IPC_NET_PLMN_LIST";
- case IPC_NET_REGIST:
- return "IPC_NET_REGIST";
- case IPC_NET_SUBSCRIBER_NUM:
- return "IPC_NET_SUBSCRIBER_NUM";
- case IPC_NET_BAND_SEL:
- return "IPC_NET_BAND_SEL";
- case IPC_NET_SERVICE_DOMAIN_CONFIG:
- return "IPC_NET_SERVICE_DOMAIN_CONFIG";
- case IPC_NET_POWERON_ATTACH:
- return "IPC_NET_POWERON_ATTACH";
- case IPC_NET_MODE_SEL:
- return "IPC_NET_MODE_SEL";
- case IPC_NET_ACQ_ORDER:
- return "IPC_NET_ACQ_ORDER";
- case IPC_NET_IDENTITY:
- return "IPC_NET_IDENTITY";
- case IPC_NET_PREFERRED_NETWORK_INFO:
- return "IPC_NET_PREFERRED_NETWORK_INFO";
- case IPC_SND_SPKR_VOLUME_CTRL:
- return "IPC_SND_SPKR_VOLUME_CTRL";
- case IPC_SND_MIC_MUTE_CTRL:
- return "IPC_SND_MIC_MUTE_CTRL";
- case IPC_SND_AUDIO_PATH_CTRL:
- return "IPC_SND_AUDIO_PATH_CTRL";
- case IPC_SND_AUDIO_SOURCE_CTRL:
- return "IPC_SND_AUDIO_SOURCE_CTRL";
- case IPC_SND_LOOPBACK_CTRL:
- return "IPC_SND_LOOPBACK_CTRL";
- case IPC_SND_VOICE_RECORDING_CTRL:
- return "IPC_SND_VOICE_RECORDING_CTRL";
- case IPC_SND_VIDEO_CALL_CTRL:
- return "IPC_SND_VIDEO_CALL_CTRL";
- case IPC_SND_RINGBACK_TONE_CTRL:
- return "IPC_SND_RINGBACK_TONE_CTRL";
- case IPC_SND_CLOCK_CTRL:
- return "IPC_SND_CLOCK_CTRL";
- case IPC_SND_WB_AMR_STATUS:
- return "IPC_SND_WB_AMR_STATUS";
- case IPC_MISC_ME_VERSION:
- return "IPC_MISC_ME_VERSION";
- case IPC_MISC_ME_IMSI:
- return "IPC_MISC_ME_IMSI";
- case IPC_MISC_ME_SN:
- return "IPC_MISC_ME_SN";
- case IPC_MISC_TIME_INFO:
- return "IPC_MISC_TIME_INFO";
- case IPC_MISC_DEBUG_LEVEL:
- return "IPC_MISC_DEBUG_LEVEL";
- case IPC_SVC_ENTER:
- return "IPC_SVC_ENTER";
- case IPC_SVC_END:
- return "IPC_SVC_END";
- case IPC_SVC_PRO_KEYCODE:
- return "IPC_SVC_PRO_KEYCODE";
- case IPC_SVC_SCREEN_CFG:
- return "IPC_SVC_SCREEN_CFG";
- case IPC_SVC_DISPLAY_SCREEN:
- return "IPC_SVC_DISPLAY_SCREEN";
- case IPC_SVC_CHANGE_SVC_MODE:
- return "IPC_SVC_CHANGE_SVC_MODE";
- case IPC_SVC_DEVICE_TEST:
- return "IPC_SVC_DEVICE_TEST";
- case IPC_SVC_DEBUG_DUMP:
- return "IPC_SVC_DEBUG_DUMP";
- case IPC_SVC_DEBUG_STRING:
- return "IPC_SVC_DEBUG_STRING";
- case IPC_SS_WAITING:
- return "IPC_SS_WAITING";
- case IPC_SS_CLI:
- return "IPC_SS_CLI";
- case IPC_SS_BARRING:
- return "IPC_SS_BARRING";
- case IPC_SS_BARRING_PW:
- return "IPC_SS_BARRING_PW";
- case IPC_SS_FORWARDING:
- return "IPC_SS_FORWARDING";
- case IPC_SS_INFO:
- return "IPC_SS_INFO";
- case IPC_SS_MANAGE_CALL:
- return "IPC_SS_MANAGE_CALL";
- case IPC_SS_USSD:
- return "IPC_SS_USSD";
- case IPC_SS_AOC:
- return "IPC_SS_AOC";
- case IPC_SS_RELEASE_COMPLETE:
- return "IPC_SS_RELEASE_COMPLETE";
- case IPC_GPRS_DEFINE_PDP_CONTEXT:
- return "IPC_GPRS_DEFINE_PDP_CONTEXT";
- case IPC_GPRS_QOS:
- return "IPC_GPRS_QOS";
- case IPC_GPRS_PS:
- return "IPC_GPRS_PS";
- case IPC_GPRS_PDP_CONTEXT:
- return "IPC_GPRS_PDP_CONTEXT";
- case IPC_GPRS_ENTER_DATA:
- return "IPC_GPRS_ENTER_DATA";
- case IPC_GPRS_SHOW_PDP_ADDR:
- return "IPC_GPRS_SHOW_PDP_ADDR";
- case IPC_GPRS_MS_CLASS:
- return "IPC_GPRS_MS_CLASS";
- case IPC_GPRS_3G_QUAL_SRVC_PROFILE:
- return "IPC_GPRS_3G_QUAL_SRVC_PROFILE";
- case IPC_GPRS_IP_CONFIGURATION:
- return "IPC_GPRS_IP_CONFIGURATION";
- case IPC_GPRS_DEFINE_SEC_PDP_CONTEXT:
- return "IPC_GPRS_DEFINE_SEC_PDP_CONTEXT";
- case IPC_GPRS_TFT:
- return "IPC_GPRS_TFT";
- case IPC_GPRS_HSDPA_STATUS:
- return "IPC_GPRS_HSDPA_STATUS";
- case IPC_GPRS_CURRENT_SESSION_DATA_COUNTER:
- return "IPC_GPRS_CURRENT_SESSION_DATA_COUNTER";
- case IPC_GPRS_DATA_DORMANT:
- return "IPC_GPRS_DATA_DORMANT";
- case IPC_GPRS_PIN_CTRL:
- return "IPC_GPRS_PIN_CTRL";
- case IPC_GPRS_CALL_STATUS:
- return "IPC_GPRS_CALL_STATUS";
- case IPC_GPRS_PORT_LIST:
- return "IPC_GPRS_PORT_LIST";
- case IPC_SAT_PROFILE_DOWNLOAD:
- return "IPC_SAT_PROFILE_DOWNLOAD";
- case IPC_SAT_ENVELOPE_CMD:
- return "IPC_SAT_ENVELOPE_CMD";
- case IPC_SAT_PROACTIVE_CMD:
- return "IPC_SAT_PROACTIVE_CMD";
- case IPC_SAT_TERMINATE_USAT_SESSION:
- return "IPC_SAT_TERMINATE_USAT_SESSION";
- case IPC_SAT_EVENT_DOWNLOAD:
- return "IPC_SAT_EVENT_DOWNLOAD";
- case IPC_SAT_PROVIDE_LOCAL_INFO:
- return "IPC_SAT_PROVIDE_LOCAL_INFO";
- case IPC_SAT_POLLING:
- return "IPC_SAT_POLLING";
- case IPC_SAT_REFRESH:
- return "IPC_SAT_REFRESH";
- case IPC_SAT_SETUP_EVENT_LIST:
- return "IPC_SAT_SETUP_EVENT_LIST";
- case IPC_SAT_CALL_CONTROL_RESULT:
- return "IPC_SAT_CALL_CONTROL_RESULT";
- case IPC_SAT_IMAGE_CLUT:
- return "IPC_SAT_IMAGE_CLUT";
- case IPC_SAT_SETUP_CALL_PROCESSING:
- return "IPC_SAT_SETUP_CALL_PROCESSING";
- case IPC_IMEI_START:
- return "IPC_IMEI_START";
- case IPC_IMEI_CHECK_DEVICE_INFO:
- return "IPC_IMEI_CHECK_DEVICE_INFO";
- case IPC_RFS_NV_READ_ITEM:
- return "IPC_RFS_NV_READ_ITEM";
- case IPC_RFS_NV_WRITE_ITEM:
- return "IPC_RFS_NV_WRITE_ITEM";
- case IPC_GEN_PHONE_RES:
- return "IPC_GEN_PHONE_RES";
- default:
- snprintf((char *) &command_string, sizeof(command_string),
- "0x%04x", command);
- return command_string;
- }
-}
-
-const char *ipc_group_string(unsigned char group)
-{
- static char group_string[5] = { 0 };
-
- switch (group) {
- case IPC_GROUP_PWR:
- return "IPC_GROUP_PWR";
- case IPC_GROUP_CALL:
- return "IPC_GROUP_CALL";
- case IPC_GROUP_SMS:
- return "IPC_GROUP_SMS";
- case IPC_GROUP_SEC:
- return "IPC_GROUP_SEC";
- case IPC_GROUP_PB:
- return "IPC_GROUP_PB";
- case IPC_GROUP_DISP:
- return "IPC_GROUP_DISP";
- case IPC_GROUP_NET:
- return "IPC_GROUP_NET";
- case IPC_GROUP_SND:
- return "IPC_GROUP_SND";
- case IPC_GROUP_MISC:
- return "IPC_GROUP_MISC";
- case IPC_GROUP_SVC:
- return "IPC_GROUP_SVC";
- case IPC_GROUP_SS:
- return "IPC_GROUP_SS";
- case IPC_GROUP_GPRS:
- return "IPC_GROUP_GPRS";
- case IPC_GROUP_SAT:
- return "IPC_GROUP_SAT";
- case IPC_GROUP_CFG:
- return "IPC_GROUP_CFG";
- case IPC_GROUP_IMEI:
- return "IPC_GROUP_IMEI";
- case IPC_GROUP_GPS:
- return "IPC_GROUP_GPS";
- case IPC_GROUP_SAP:
- return "IPC_GROUP_SAP";
- case IPC_GROUP_RFS:
- return "IPC_GROUP_RFS";
- case IPC_GROUP_GEN:
- return "IPC_GROUP_GEN";
- default:
- snprintf((char *) &group_string, sizeof(group_string), "0x%02x",
- (unsigned int)group_string);
- return group_string;
- }
-}
-
int ipc_data_dump(struct ipc_client *client, const void *data, size_t size)
{
unsigned int cols = 8;
diff --git a/samsung-ipc/modems/xmm626/xmm626_kernel_smdk4412.c b/samsung-ipc/modems/xmm626/xmm626_kernel_smdk4412.c
index c6b1578..cdac3e4 100644
--- a/samsung-ipc/modems/xmm626/xmm626_kernel_smdk4412.c
+++ b/samsung-ipc/modems/xmm626/xmm626_kernel_smdk4412.c
@@ -19,11 +19,13 @@
*/
#define _GNU_SOURCE
-#include <stdlib.h>
+
+#include <fcntl.h>
#include <stdio.h>
-#include <unistd.h>
+#include <stdlib.h>
#include <string.h>
-#include <fcntl.h>
+#include <unistd.h>
+
#include <sys/ioctl.h>
#include <sys/select.h>
@@ -582,11 +584,17 @@ char *xmm626_kernel_smdk4412_gprs_get_iface(
__attribute__((unused)) struct ipc_client *client, unsigned int cid)
{
char *iface = NULL;
+ int rc;
if (cid > XMM626_SEC_MODEM_GPRS_IFACE_COUNT)
return NULL;
- asprintf(&iface, "%s%d", XMM626_SEC_MODEM_GPRS_IFACE_PREFIX, cid - 1);
+ rc = asprintf(&iface, "%s%d",
+ XMM626_SEC_MODEM_GPRS_IFACE_PREFIX, cid - 1);
+ if (rc == -1) {
+ ipc_client_log(client, "%s: asprintf failed", __func__);
+ return NULL;
+ }
return iface;
}
diff --git a/samsung-ipc/partitions/android/android.c b/samsung-ipc/partitions/android/android.c
index 9ec6ed4..9d2322f 100644
--- a/samsung-ipc/partitions/android/android.c
+++ b/samsung-ipc/partitions/android/android.c
@@ -84,8 +84,7 @@ int open_android_modem_partition_by_name(struct ipc_client *client,
return -errno;
}
- strncpy(path, partitions_dirnames[i],
- strlen(partitions_dirnames[i]));
+ strcpy(path, partitions_dirnames[i]);
strcat(path, name);
ipc_client_log(client, "%s: Trying to open %s",
diff --git a/samsung-ipc/tests/Makefile.am b/samsung-ipc/tests/Makefile.am
index d049c74..ad4280e 100644
--- a/samsung-ipc/tests/Makefile.am
+++ b/samsung-ipc/tests/Makefile.am
@@ -1,13 +1,20 @@
NULL =
+EXTRA_DIST = $(NULL)
AM_CFLAGS = \
- -I$(top_srcdir)/include \
- -I$(top_srcdir)/samsung-ipc \
- $(OPENSSL_CFLAGS) \
- $(NULL)
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/samsung-ipc \
+ $(OPENSSL_CFLAGS) \
+ $(NULL)
+
+AM_LDFLAGS = $(ALL_STATIC_LDFLAGS)
+
+if WANT_STRICT_CFLAGS
+AM_CFLAGS += $(STRICT_CFLAGS)
+endif
if WANT_DEBUG
-AM_CFLAGS += -ggdb -O0 -DDEBUG
+AM_CFLAGS += -DDEBUG
endif
bin_PROGRAMS = libsamsung-ipc-test
@@ -19,11 +26,14 @@ libsamsung_ipc_test_SOURCES = \
$(NULL)
libsamsung_ipc_test_LDADD = $(top_builddir)/samsung-ipc/libsamsung-ipc.la
-libsamsung_ipc_test_LDFLAGS =
# TODO: Find a way to make test more modular and represent each run of
# libsamsung-ipc-test in TEST while having it implemented in a single
# python file
-PY_LOG_COMPILER = $(PYTHON)
+if WANT_VALGRIND_CHECKING
+AM_TESTS_ENVIRONMENT = VALGRIND='$(VALGRIND)'; export VALGRIND;
+endif
+PY_LOG_COMPILER = $(PYTHON3)
TEST_EXTENSIONS = .py
TESTS = libsamsung-ipc-test.py
+EXTRA_DIST += $(TESTS)
diff --git a/samsung-ipc/tests/libsamsung-ipc-test.py b/samsung-ipc/tests/libsamsung-ipc-test.py
index 328f4f0..5435013 100755
--- a/samsung-ipc/tests/libsamsung-ipc-test.py
+++ b/samsung-ipc/tests/libsamsung-ipc-test.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# This file is part of libsamsung-ipc.
#
@@ -26,14 +26,26 @@ class libsamsung_ipc_test(object):
def __init__(self):
srcdir = os.environ.get('srcdir', None)
- # Enable also to test without automake
- if not srcdir:
- srcdir = os.path.dirname(sys.argv[0])
+ command_path = ''
+ if srcdir:
+ command_path = '.' + os.sep + 'libsamsung-ipc-test'
+ # Enable to run tests without automake
+ else:
+ command_path = os.path.dirname(sys.argv[0]) \
+ + os.sep \
+ + 'libsamsung-ipc-test'
- self.run = sh.Command(srcdir + os.sep + "libsamsung-ipc-test")
+ if 'VALGRIND' in os.environ:
+ self.run = sh.Command(os.environ['VALGRIND'])
+ self.run = self.run.bake('-v',
+ '--log-file=valgrind.%p.log',
+ '--leak-check=full',
+ command_path)
+ else:
+ self.run = sh.Command(command_path)
def run_all_tests(self):
- output = str(self.run("list-tests")).split(os.linesep)
+ output = str(self.run('list-tests')).split(os.linesep)
# Remove the last line break from the output
output.remove('')
@@ -44,7 +56,7 @@ class libsamsung_ipc_test(object):
output.pop(0)
for test_name in output:
- self.run("test", test_name.replace(' ', ''))
+ self.run('test', test_name.replace(' ', ''))
def main():
tests = libsamsung_ipc_test()
diff --git a/samsung-ipc/tests/partitions/android.c b/samsung-ipc/tests/partitions/android.c
index 708480a..7b067e9 100644
--- a/samsung-ipc/tests/partitions/android.c
+++ b/samsung-ipc/tests/partitions/android.c
@@ -42,17 +42,123 @@ static char const * const dummy_modem_image_paths[] = {
NULL
};
+int delete_dummy_modem_image(struct ipc_client *client,
+ __attribute__((unused)) const char * const path)
+{
+ int rc;
+ char *endp;
+ char *dir;
+
+ rc = unlink(path);
+ if (rc == -1) {
+ rc = errno;
+ if (rc != ENOENT) {
+ ipc_client_log(client,
+ "%s: unlink %s failed with error %d: %s",
+ __func__, path, rc, strerror(rc));
+ errno = rc;
+ return -1;
+ }
+ }
+
+ endp = strrchr(path, '/');
+
+ dir = malloc(endp - path + 1);
+ if (dir == NULL) {
+ rc = errno;
+ ipc_client_log(client,
+ "%s: calloc failed with error %d: %s",
+ __func__, rc, strerror(rc));
+ errno = rc;
+ return -1;
-int create_dummy_modem_image(__attribute__((unused)) struct ipc_client *client,
+ }
+
+ memcpy(dir, path, endp - path);
+ dir[endp - path] = '\0';
+
+ rc = rmdir(dir);
+ if (rc == -1) {
+ rc = errno;
+ if (rc != ENOENT) {
+ ipc_client_log(client,
+ "%s: rmdir %s failed with error %d: %s",
+ __func__, dir, rc, strerror(rc));
+
+ free(dir);
+ errno = rc;
+ return -1;
+ }
+ }
+
+ free(dir);
+ return 0;
+}
+
+
+int create_dummy_modem_image(struct ipc_client *client,
__attribute__((unused)) const char * const path)
{
- /* TODO: replace it by C code but make sure that the replacement code
- * is as robust as the shell commands
- */
- system("mkdir -p /tmp/libsamsung-ipc.55f4731d2e11e85bd889/");
- system("touch /tmp/libsamsung-ipc.55f4731d2e11e85bd889/modem.img");
+ int fd;
+ int rc;
+
+ rc = mkdir("/tmp/", 0755);
+ if (rc == -1) {
+ rc = errno;
+ if (rc != EEXIST) {
+ ipc_client_log(client,
+ "%s: mkdir %s failed with error %d: %s",
+ __func__, "/tmp/", rc, strerror(rc));
+ return -1;
+ }
+ }
+
+ rc = mkdir("/tmp/libsamsung-ipc.55f4731d2e11e85bd889/", 0755);
+ if (rc == -1) {
+ rc = errno;
+ if (rc != EEXIST) {
+ ipc_client_log(client,
+ "%s: mkdir %s failed with error %d: %s",
+ __func__,
+ "/tmp/libsamsung-ipc.55f4731d2e11e85bd889/",
+ rc, strerror(rc));
+ return -1;
+ }
+ }
+
+ fd = open("/tmp/libsamsung-ipc.55f4731d2e11e85bd889/modem.img",
+ O_CREAT, 0755);
+ if (fd == -1) {
+ rc = errno;
+ ipc_client_log(client,
+ "%s: open %s failed with error %d: %s",
+ __func__,
+ "/tmp/libsamsung-ipc.55f4731d2e11e85bd889/modem.img",
+ rc, strerror(rc));
+ goto error;
+ }
+
+ rc = close(fd);
+ if (rc == -1) {
+ rc = errno;
+ ipc_client_log(client,
+ "%s: close %s failed with error %d: %s",
+ __func__,
+ "/tmp/libsamsung-ipc.55f4731d2e11e85bd889/modem.img",
+ rc, strerror(rc));
+ goto error;
+ }
return 0;
+
+error:
+ rc = delete_dummy_modem_image(
+ client, "/tmp/libsamsung-ipc.55f4731d2e11e85bd889/modem.img");
+ if (rc == -1)
+ ipc_client_log(client,
+ "%s: delete_dummy_modem_image %s failed with error -1",
+ __func__);
+ return -1;
}
int test_open_android_modem_partition(struct ipc_client *client)
@@ -92,5 +198,15 @@ int test_open_android_modem_partition(struct ipc_client *client)
return -1;
}
+ rc = delete_dummy_modem_image(
+ client, "/tmp/libsamsung-ipc.55f4731d2e11e85bd889/modem.img");
+ if (rc == -1) {
+ rc = errno;
+ ipc_client_log(client,
+ "%s: delete_dummy_modem_image() failed with errror %d: %s\n",
+ __func__, rc, strerror(rc));
+ return -1;
+ }
+
return 0;
}
diff --git a/samsung-ipc/utils.c b/samsung-ipc/utils.c
index 44cbe2d..18f5d2b 100644
--- a/samsung-ipc/utils.c
+++ b/samsung-ipc/utils.c
@@ -295,7 +295,7 @@ int network_iface_up(const char *iface, int domain, int type)
return -1;
memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, iface, IFNAMSIZ);
+ memcpy(ifr.ifr_name, iface, IFNAMSIZ);
fd = socket(domain, type, 0);
if (fd < 0)
@@ -334,7 +334,7 @@ int network_iface_down(const char *iface, int domain, int type)
return -1;
memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, iface, IFNAMSIZ);
+ memcpy(ifr.ifr_name, iface, IFNAMSIZ);
fd = socket(domain, type, 0);
if (fd < 0)
diff --git a/scripts/PKGBUILD b/scripts/PKGBUILD
new file mode 100644
index 0000000..155a765
--- /dev/null
+++ b/scripts/PKGBUILD
@@ -0,0 +1,55 @@
+# Copyright (C) 2022 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
+# 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.
+
+pkgname=libsamsung-ipc-git
+pkgver=0.3.1.r703.7c5e96a
+pkgrel=1
+pkgdesc="samsung-ipc modem protocol implementation."
+arch=('armv7h' 'i686' 'x86_64')
+license=('GPL2')
+makedepends=('autoconf'
+ 'automake'
+ 'coreutils'
+ 'ddrescue'
+ 'gawk'
+ 'grep'
+ 'libtool'
+ 'pkg-config'
+ 'python'
+ 'python-sh'
+ 'sed'
+ 'valgrind')
+depends=('openssl')
+
+pkgver() {
+ _base_version="0.3.1"
+ _base_revision="5cb3e7cb99701cae738693f2d6a6797a4d2df679"
+
+ if [ -d ../../.git ] ; then
+ printf "%s.r%s.%s" \
+ "${_base_version}" \
+ "$(git -C ../../ rev-list --count HEAD)" \
+ "$(git -C ../../ rev-parse --short HEAD)"
+ else
+ date "+%Y%m%d"
+ fi
+}
+
+build() {
+ ../../autogen.sh
+ ../../configure \
+ --prefix=/usr \
+ --enable-debug --enable-valgrind-tests --enable-strict-cflags
+ make
+}
+
+check() {
+ make check
+}
+
+package(){
+ make DESTDIR="$pkgdir" install
+}
diff --git a/scripts/guix.scm b/scripts/guix.scm
index a917a82..6343208 100644
--- a/scripts/guix.scm
+++ b/scripts/guix.scm
@@ -41,56 +41,124 @@
;;; to all the exported functions, and make a new release when that is
;;; done.
-(use-modules
- (ice-9 popen)
- (ice-9 rdelim)
- (sxml ssax input-parse)
- ((guix licenses) #:prefix license:)
- (guix build-system android-ndk)
- (guix build-system gnu)
- (guix gexp)
- (guix git-download)
- (guix packages)
- (gnu packages android)
- (gnu packages autotools)
- (gnu packages disk)
- (gnu packages linux)
- (gnu packages llvm)
- (gnu packages pkg-config)
- (gnu packages python)
- (gnu packages python-xyz)
- (gnu packages tls))
+(use-modules (ice-9 popen)
+ (ice-9 rdelim)
+ (ice-9 regex)
+ (ice-9 textual-ports)
+ (sxml ssax input-parse)
+ ((guix licenses)
+ #:prefix license:)
+ (guix build-system android-ndk)
+ (guix build-system gnu)
+ (guix gexp)
+ (guix git-download)
+ (guix packages)
+ (guix profiles)
+ (guix transformations)
+ (gnu packages)
+ (gnu packages android)
+ (gnu packages autotools)
+ (gnu packages base)
+ (gnu packages curl)
+ (gnu packages disk)
+ (gnu packages linux)
+ (gnu packages llvm)
+ (gnu packages pkg-config)
+ (gnu packages python)
+ (gnu packages python-xyz)
+ (gnu packages tls)
+ (gnu packages valgrind))
+
+;; We need a more recent version of android-make-stub as it now
+;; support passing LOCAL_MODULE= to make to build specific local
+;; modules. This is needed because android-make-stub doesn't handle
+;; dependencies, so we need to make sure that libsamsung-ipc is built
+;; first. In addition we need a fix to make the applications that
+;; depend on libsamsung-ipc find libsamsung-ipc's includes directory.
+(define with-fixed-android-make-stub
+ (options->transformation '((with-commit . "android-make-stub=4bc0e068c32fe525741da00af064ddc079de7e4b"))))
+
+(define (parse-android.mk port modules-list)
+ (let* ((line (read-line port)))
+ (if (not (eof-object? line))
+ (let* ((line-parts (string-split line #\space)))
+ (if (string=? (car line-parts) "LOCAL_MODULE")
+ (if (not (string=? (list-ref line-parts 2) "libsamsung-ipc"))
+ (if (string=? modules-list "")
+ (parse-android.mk port
+ (list-ref line-parts 2))
+ (parse-android.mk port
+ (string-append modules-list " "
+ (list-ref line-parts 2))))
+ (parse-android.mk port modules-list))
+ (parse-android.mk port modules-list))) modules-list)))
+
+(define android-local-modules-list
+ (let* ((port (open-input-file "./Android.mk"))
+ (local-modules (parse-android.mk port "")))
+ (close-input-port port)
+ (string-split local-modules #\space)))
(define %common-strict-cflags
- (string-append
- " CFLAGS="
- " -W"
- " -Wall"
- " -Werror"
- " -Werror=address"
- " -Werror=return-type"
- " -Werror=sequence-point"
- " -Winit-self"
- " -Wno-unused"
- " -Wpointer-arith"
- " -Wunused"
- " -Wunused-function"))
+ (let* ((port (open-input-pipe "./strict-cflags.sh"))
+ (str (read-line port)))
+ (close-pipe port)
+ (string-append "CFLAGS=" str)))
(define %clang-strict-cflags
- (string-append
- "-Werror=non-virtual-dtor"))
+ (string-append "-Werror=non-virtual-dtor"))
(define %commit
(let* ((port (open-input-pipe
"git --no-pager log --oneline HEAD -1 --format='%H'"))
- (str (read-line port)))
- (close-pipe port)
- str))
+ (str (read-line port)))
+ (close-pipe port) str))
(define %local-source
- (local-file
- (dirname (dirname (current-filename)))
- #:recursive? #t))
+ (local-file (dirname (dirname (current-filename)))
+ #:recursive? #t))
+
+(define android-make
+ #~(lambda (target android-local-modules)
+ (lambda* (#:key inputs make-flags native-inputs outputs
+ #:allow-other-keys)
+ (substitute* "Android.mk"
+ (("BUILD_SHARED_LIBRARY")
+ "BUILD_HOST_SHARED_LIBRARY")
+ (("BUILD_EXECUTABLE")
+ "BUILD_HOST_EXECUTABLE"))
+ ((assoc-ref %standard-phases target)
+ #:inputs inputs
+ #:outputs outputs
+ #:make-flags (append make-flags
+ '("LDFLAGS=-lssl -lcrypto"
+ "LOCAL_MODULE=libsamsung-ipc"
+ "SO=libsamsung-ipc.so")))
+ (map-in-order (lambda (local-module)
+ ((assoc-ref %standard-phases target)
+ #:inputs inputs
+ #:outputs outputs
+ #:make-flags (append make-flags
+ (list (string-append
+ "LDFLAGS=-Wl,-rpath="
+ #$output
+ "/lib -lssl -lcrypto -L .")
+ (string-append
+ "LOCAL_MODULE="
+ local-module)))))
+ android-local-modules))))
+
+(define android-phases
+ #~(modify-phases %standard-phases
+ (delete 'bootstrap)
+ (replace 'build
+ (#$android-make
+ 'build
+ '#$android-local-modules-list))
+ (replace 'install
+ (#$android-make
+ 'install
+ '#$android-local-modules-list))))
(define-public libsamsung-ipc
(package
@@ -98,116 +166,151 @@
(version (git-version "0.0" "HEAD" %commit))
(source %local-source)
(build-system gnu-build-system)
- (native-inputs
- `(("autoreconf" ,autoconf)
- ("aclocal" ,automake)
- ("ddrescue", ddrescue)
- ("libtool" ,libtool)
- ("pkgconfig" ,pkg-config)
- ("python" ,python)
- ("python-sh" ,python-sh)))
- (inputs
- `(("openssl" ,openssl)))
+ (native-inputs (list autoconf
+ automake
+ ddrescue
+ `(,(canonical-package glibc) "debug")
+ libtool
+ pkg-config
+ python
+ python-sh
+ valgrind))
+ (inputs (list curl libressl))
(arguments
- `(#:phases
- (modify-phases %standard-phases
- (add-before 'build 'patch-python
- (lambda _
- (substitute* (find-files "." ".*\\.py$")
- (("/usr/bin/env python") (which "python3")))
- #t)))))
- (synopsis "libsamsung-ipc is a free software implementation of the Samsung IPC modem protocol")
+ (list #:phases #~(modify-phases %standard-phases
+ (add-before 'build 'fix-valgrind
+ (lambda _
+ (substitute* (find-files "." ".*\\.py$")
+ (("'--leak-check=full',")
+ (string-append
+ "'--leak-check=full', '--extra-debuginfo-path="
+ (ungexp (this-package-native-input "glibc")
+ "debug") "/lib/debug',"))))))
+ #:configure-flags #~(list "--enable-debug"
+ "--enable-valgrind-tests")))
+ (synopsis
+ "libsamsung-ipc is a free software implementation of the Samsung IPC modem protocol")
(description
"libsamsung-ipc is a free software implementation of the Samsung IPC modem protocol,
found in many Samsung smartphones and tablets.")
(home-page "https://www.replicant.us")
(license license:gpl2+)))
+(define is-file-static
+ #~(lambda (readelf path)
+ ;; str is also eof if the file doesn't exist
+ (if (not (file-exists? tool)) #f
+ (let* ((port (open-input-pipe (string-append readelf " --dyn-syms "
+ path)))
+ (str (read-line port)))
+ (close-pipe port)
+ (eof-object? str)))))
+
+(define-public libsamsung-ipc-static
+ (package
+ (inherit libsamsung-ipc)
+ (name "libsamsung-ipc-static")
+ (native-inputs (list autoconf
+ automake
+ binutils
+ ddrescue
+ libtool
+ pkg-config
+ python
+ python-sh))
+ ;; The libressl package contains .a in
+ ;; /gnu/store/[...]-libressl-[...]/lib/*.a
+ (inputs (list curl libressl))
+ (arguments
+ (list #:modules '((ice-9 popen)
+ (ice-9 rdelim)
+ (guix build utils)
+ (guix build gnu-build-system))
+ #:tests? #f
+ #:phases #~(modify-phases %standard-phases
+ ;; https-send-sms depends on curl and Guix doesn't have
+ ;; a static libcurl.
+ (add-after 'unpack 'remove-https-send-sms
+ (lambda _
+ (substitute* "tools/Makefile.am"
+ (("https-send-sms \\\\")
+ "\\"))))
+ (add-after 'compress-documentation 'check-static-files
+ (lambda _
+ (display "Checking static files:\n")
+ (map-in-order (lambda (tool)
+ (if (#$is-file-static
+ (string-append #$(this-package-native-input
+ "binutils")
+ "/bin/readelf") tool)
+ (display (string-append
+ "[ OK ] "
+ (basename tool) ": "
+ tool "\n"))
+ ((lambda _
+ (display (string-append
+ "[ !! ] "
+ (basename tool)
+ ": " tool "\n"))
+ (#f)))))
+ (list
+ "samsung-ipc/tests/libsamsung-ipc-test"
+ "tools/ipc-test"
+ "tools/nv_data-imei"
+ "tools/nv_data-md5"
+ "tools/ipc-modem/ipc-modem")))))
+ #:configure-flags #~(list "--enable-debug" "--enable-static=yes"
+ "--enable-shared=no"
+ "--enable-static-progs")))))
+
(define-public libsamsung-ipc-gcc-android
(package
- (inherit libsamsung-ipc)
+ (inherit libsamsung-ipc)
(name "libsamsung-ipc-gcc-android")
(build-system android-ndk-build-system)
- (inputs
- `(("android-libutils" ,android-libutils)
- ("libcrypto" ,openssl)))
+ (inputs (list android-libutils curl libressl))
(native-inputs '())
(arguments
- `(#:phases
- (modify-phases %standard-phases
- (delete 'bootstrap)
- (add-before 'build 'patch-host
- (lambda _
- (substitute* "Android.mk"
- (("BUILD_SHARED_LIBRARY") "BUILD_HOST_SHARED_LIBRARY")
- (("BUILD_STATIC_LIBRARY") "BUILD_HOST_STATIC_LIBRARY")
- (("BUILD_STATIC_EXECUTABLE") "BUILD_HOST_STATIC_EXECUTABLE"))
- #t)))
- #:make-flags (list ,%common-strict-cflags)))))
+ (list #:make-flags #~(list #$%common-strict-cflags
+ #$%clang-strict-cflags)
+ #:phases android-phases))))
(define-public libsamsung-ipc-gcc-autotools
(package
- (inherit libsamsung-ipc)
- (name "libsamsung-ipc-gcc-autotools")
- (arguments
- `(#:phases
- (modify-phases %standard-phases
- (add-before 'build 'patch-python
- (lambda _
- (substitute* (find-files "." ".*\\.py$")
- (("/usr/bin/env python") (which "python3")))
- #t)))
- #:make-flags (list ,%common-strict-cflags)))))
+ (inherit libsamsung-ipc)
+ (name "libsamsung-ipc-gcc-autotools")
+ (arguments
+ (list #:configure-flags #~(list "--enable-debug")
+ #:make-flags #~(list #$%common-strict-cflags)))))
(define-public libsamsung-ipc-clang-autotools
(package
- (inherit libsamsung-ipc)
- (name "libsamsung-ipc-gcc-autotools")
- (native-inputs
- `(("autoreconf" ,autoconf)
- ("aclocal" ,automake)
- ("ddrescue", ddrescue)
- ("libtool" ,libtool)
- ("pkgconfig" ,pkg-config)
- ("python" ,python)
- ("python-sh" ,python-sh)
- ("clang" ,clang)))
+ (inherit libsamsung-ipc)
+ (name "libsamsung-ipc-clang-autotools")
+ (native-inputs (list autoconf
+ automake
+ ddrescue
+ libtool
+ pkg-config
+ python
+ python-sh
+ clang))
(arguments
- `(#:phases
- (modify-phases %standard-phases
- (add-before 'build 'patch-python
- (lambda _
- (substitute* (find-files "." ".*\\.py$")
- (("/usr/bin/env python") (which "python3")))
- #t)))
- #:make-flags (list ,%common-strict-cflags ,%clang-strict-cflags)))))
+ (list #:configure-flags #~(list "--enable-debug")
+ #:make-flags #~(list #$%common-strict-cflags
+ #$%clang-strict-cflags)))))
(define-public libsamsung-ipc-clang-android
(package
- (inherit libsamsung-ipc)
+ (inherit libsamsung-ipc)
(name "libsamsung-ipc-clang-android")
(build-system android-ndk-build-system)
- (inputs
- `(("android-libutils" ,android-libutils)
- ("libcrypto" ,openssl)
- ("clang" ,clang)))
+ (inputs (list android-libutils clang curl libressl))
(native-inputs '())
(arguments
- `(#:phases
- (modify-phases %standard-phases
- (delete 'bootstrap)
- (add-before 'build 'patch-host
- (lambda _
- (substitute* "Android.mk"
- (("BUILD_SHARED_LIBRARY") "BUILD_HOST_SHARED_LIBRARY")
- (("BUILD_STATIC_LIBRARY") "BUILD_HOST_STATIC_LIBRARY")
- (("BUILD_STATIC_EXECUTABLE") "BUILD_HOST_STATIC_EXECUTABLE"))
- #t))
- (add-after 'patch-host 'prepare-build-environment
- (lambda* (#:key inputs #:allow-other-keys)
- (setenv "CC" "clang")
- #t)))
- #:make-flags (list ,%common-strict-cflags ,%clang-strict-cflags)))))
+ (list #:make-flags #~(list #$%common-strict-cflags
+ #$%clang-strict-cflags)
+ #:phases android-phases))))
;; Combinaisons:
;; +--------------------------------+----------+----------+--------------+--------------+
@@ -226,7 +329,8 @@ found in many Samsung smartphones and tablets.")
;; +--------------------------------+----------+----------+--------------+--------------+
(list libsamsung-ipc
- libsamsung-ipc-gcc-android
- libsamsung-ipc-gcc-autotools
- libsamsung-ipc-clang-android
- libsamsung-ipc-clang-autotools)
+ libsamsung-ipc-static
+ (with-fixed-android-make-stub libsamsung-ipc-clang-android)
+ (with-fixed-android-make-stub libsamsung-ipc-gcc-android)
+ libsamsung-ipc-clang-autotools
+ libsamsung-ipc-gcc-autotools)
diff --git a/scripts/manifest.scm b/scripts/manifest.scm
new file mode 100644
index 0000000..dfc82c7
--- /dev/null
+++ b/scripts/manifest.scm
@@ -0,0 +1,59 @@
+;;; Copyright © 2021 Denis Carikli <GNUtoo@cyberdimension.org>
+;;;
+;;; This file 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 file 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 GNU Guix. If not, see <http://www.gnu.org/licenses/>.
+;;; The guix.scm file is a convention: A file named guix.scm is
+;;; found in several project source code, either in the top
+;;; directory or in sub-directories like contrib for instance.
+
+;;; This file can be used to setup a development environment for Guix
+;;; users with the following command:
+;;; guix shell --pure --container -f scripts/manifest.scm
+
+(use-modules
+ (gnu packages autotools)
+ (gnu packages base)
+ (gnu packages code)
+ (gnu packages commencement)
+ (gnu packages compression)
+ (gnu packages curl)
+ (gnu packages disk)
+ (gnu packages gawk)
+ (gnu packages pkg-config)
+ (gnu packages python)
+ (gnu packages python-xyz)
+ (gnu packages tls))
+
+(list
+ autoconf
+ automake
+ bzip2
+ coreutils
+ curl
+ ddrescue
+ diffutils
+ findutils
+ gawk
+ gzip
+ gcc-toolchain
+ grep
+ lcov
+ libtool
+ gnu-make
+ openssl
+ pkg-config
+ python
+ python-sh
+ sed
+ tar
+ xz)
diff --git a/scripts/rebase-build-check-android.sh b/scripts/rebase-build-check-android.sh
new file mode 100755
index 0000000..e43e3c6
--- /dev/null
+++ b/scripts/rebase-build-check-android.sh
@@ -0,0 +1,102 @@
+#!/bin/bash
+# -*- coding: utf-8 -*-
+# Copyright (C) 2022 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
+#
+# 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 Affero 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 <https://www.gnu.org/licenses/>.
+set -e
+
+usage()
+{
+ printf "Usage:\n"
+ printf "%s build-from <base-commit-ref> " "$0"
+ printf "# Build all commits since <base-commit-ref>\n" "%0"
+ printf "%s continue " "$0"
+ printf "# Continue rebasing and building commits\n" "%0"
+ exit 64; # EX_USAGE from sysexits.h
+}
+
+print_header()
+{
+ set +e
+ message="$1"
+
+ len=$(expr $(echo -n ${message} | wc -c) + 2)
+
+ nr_chars=$(expr $(expr 80 - ${len}) / 2)
+
+ i="${nr_chars}"
+
+ while [ ${i} -gt 0 ] ; do
+ echo -n "#"
+ i="$(expr ${i} - 1)"
+ done
+
+ echo -n " ${message} "
+
+ i="${nr_chars}"
+
+ while [ ${i} -gt 0 ] ; do
+ echo -n "#"
+ i="$(expr ${i} - 1)"
+ done
+ echo
+ set -e
+}
+
+build_and_git_rebase_continue()
+{
+ total_commits="$1"
+
+ total_targets="$(./vendor/replicant/build.sh targets | wc -l)"
+ parallel_tasks=$(echo "$(grep 'processor' /proc/cpuinfo | wc -l ) + 1" | bc)
+
+ local_modules="$(grep \
+ "^LOCAL_MODULE := " \
+ hardware/replicant/libsamsung-ipc/Android.mk | \
+ awk '{print $3}' | sort -u)"
+
+ source build/envsetup.sh
+
+ # Currently all the Replicant versions supported by libsamsung-ipc
+ # have an aosp_arm-eng target. Using aosp_arm-eng also ensures
+ # that TARGET_DEVICE isn't set by the device repository. This also
+ # leaves us more freedom in libsamsung-ipc as we could for
+ # instance decide to not build unused code based on TARGET_DEVICE.
+ lunch aosp_arm-eng
+
+ commit_nr=1
+ while true ; do
+ print_header "[ commit ${commit_nr} of ${total_commits} ]"
+ make "-j${parallel_tasks}" ${local_modules}
+ git -C hardware/replicant/libsamsung-ipc rebase --continue || break
+ commit_nr="$(expr ${commit_nr} + 1)"
+ done
+}
+
+if [ $# -eq 2 ] && [ "$1" == "build-from" ] ; then
+ base_commit="$2"
+ nr_commits="$(git -C hardware/replicant/libsamsung-ipc log --oneline \
+ ${base_commit}~1..HEAD --oneline | wc -l)"
+ GIT_EDITOR="sed 's#^pick #edit #g' -i " \
+ git -C hardware/replicant/libsamsung-ipc \
+ rebase -i "${base_commit}"
+
+ build_and_git_rebase_continue "${nr_commits}"
+elif [ $# -eq 1 ] && [ "$1" == "continue" ] ; then
+ nr_commits="$(git -C hardware/replicant/libsamsung-ipc \
+ log --oneline REBASE_HEAD~1..ORIG_HEAD --oneline | wc -l)"
+ build_and_git_rebase_continue "${nr_commits}"
+else
+ usage
+fi
diff --git a/scripts/rebase-build-check-gnu-linux.sh b/scripts/rebase-build-check-gnu-linux.sh
new file mode 100755
index 0000000..a909290
--- /dev/null
+++ b/scripts/rebase-build-check-gnu-linux.sh
@@ -0,0 +1,81 @@
+#!/bin/bash
+# -*- coding: utf-8 -*-
+# Copyright (C) 2022 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
+#
+# 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 Affero 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 <https://www.gnu.org/licenses/>.
+
+die()
+{
+ echo "$@"
+ exit 1;
+}
+
+usage()
+{
+ printf "Usage:\n"
+ printf "%s build-from <base-commit-ref> " "$0"
+ printf "# Build all commits since <base-commit-ref>\n" "%0"
+ printf "%s continue " "$0"
+ printf "# Continue rebasing and building commits\n" "%0"
+ exit 64; # EX_USAGE from sysexits.h
+}
+
+print_header()
+{
+ message="$1"
+
+ len=$(expr $(echo -n ${message} | wc -c) + 2)
+
+ nr_chars=$(expr $(expr 80 - ${len}) / 2)
+
+ i="${nr_chars}"
+ while [ ${i} -gt 0 ] ; do
+ echo -n "#"
+ i="$(expr ${i} - 1)"
+ done
+
+ echo -n " ${message} "
+
+ i="${nr_chars}"
+ while [ ${i} -gt 0 ] ; do
+ echo -n "#"
+ i="$(expr ${i} - 1)"
+ done
+ echo
+}
+
+build_and_git_rebase_continue()
+{
+ commits="$1"
+ commit=1
+
+ while true ; do
+ print_header "[ ${commit} of ${commits} ]"
+ guix build --file=scripts/guix.scm || die "guix build failed"
+ commit="$(expr ${commit} + 1)"
+ git rebase --continue || break
+ done
+}
+
+if [ $# -eq 2 ] && [ "$1" == "build-from" ] ; then
+ base_commit="$2"
+ nr_commits="$(git log --oneline ${base_commit}~1..HEAD --oneline | wc -l)"
+ GIT_EDITOR="sed 's#^pick #edit #g' -i " git rebase -i "${base_commit}"
+ build_and_git_rebase_continue "${nr_commits}"
+elif [ $# -eq 1 ] && [ "$1" == "continue" ] ; then
+ nr_commits="$(git log --oneline REBASE_HEAD~1..ORIG_HEAD --oneline | wc -l)"
+ build_and_git_rebase_continue "${nr_commits}"
+else
+ usage
+fi
diff --git a/strict-cflags.sh b/strict-cflags.sh
new file mode 100755
index 0000000..55380f3
--- /dev/null
+++ b/strict-cflags.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+#
+# This file is part of libsamsung-ipc.
+#
+# Copyright (C) 2022 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
+#
+# libsamsung-ipc 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 2 of the License, or
+# (at your option) any later version.
+#
+# libsamsung-ipc 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 libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
+
+strict_cflags="\
+ -W \
+ -Wall \
+ -Werror \
+ -Werror=address \
+ -Werror=return-type \
+ -Werror=sequence-point \
+ -Winit-self \
+ -Wno-unused \
+ -Wpedantic \
+ -Wpointer-arith \
+ -Wunused \
+ -Wunused-function \
+"
+
+echo ${strict_cflags}
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 4d5fa8b..024df50 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -1,11 +1,19 @@
NULL =
+EXTRA_DIST = $(NULL)
AM_CFLAGS = \
-I$(top_srcdir)/include \
+ $(LIBCURL_CFLAGS) \
$(NULL)
+AM_LDFLAGS = $(ALL_STATIC_LDFLAGS)
+
+if WANT_STRICT_CFLAGS
+AM_CFLAGS += $(STRICT_CFLAGS)
+endif
+
bin_PROGRAMS = \
- ipc-modem \
+ https-send-sms \
ipc-test \
nv_data-imei \
nv_data-md5 \
@@ -13,23 +21,24 @@ bin_PROGRAMS = \
# TODO: Find a way to make test more modular and represent each run of the
# nv_data-imei in TEST while having it implemented in a single python file
-PY_LOG_COMPILER = $(PYTHON)
+if WANT_VALGRIND_CHECKING
+AM_TESTS_ENVIRONMENT = VALGRIND='$(VALGRIND)'; export VALGRIND;
+endif
+PY_LOG_COMPILER = $(PYTHON3)
TEST_EXTENSIONS = .py
-TESTS = nv_data-imei.py \
- nv_data-md5.py
+TESTS = \
+ tests/nv_data-imei.py \
+ tests/nv_data-md5.py
+EXTRA_DIST += $(TESTS)
-ipc_modem_SOURCES = ipc-modem.c
-ipc_modem_LDADD = $(top_builddir)/samsung-ipc/libsamsung-ipc.la
-ipc_modem_LDFLAGS =
+https_send_sms_SOURCES = https-send-sms.c
+https_send_sms_LDADD = $(LIBCURL_LIBS)
ipc_test_SOURCES = ipc-test.c
ipc_test_LDADD = $(top_builddir)/samsung-ipc/libsamsung-ipc.la
-ipc_test_LDFLAGS =
nv_data_md5_SOURCES = nv_data-md5.c
nv_data_md5_LDADD = $(top_builddir)/samsung-ipc/libsamsung-ipc.la
-nv_data_md5_LDFLAGS =
-nv_data_imei_SOURCES = nv_data-imei.c
+nv_data_imei_SOURCES = nv_data-imei.c nv_data-imei.h
nv_data_imei_LDADD = $(top_builddir)/samsung-ipc/libsamsung-ipc.la
-nv_data_imei_LDFLAGS =
diff --git a/tools/https-send-sms.c b/tools/https-send-sms.c
new file mode 100644
index 0000000..80ad00b
--- /dev/null
+++ b/tools/https-send-sms.c
@@ -0,0 +1,205 @@
+/*
+ * This file is part of libsamsung-ipc.
+ *
+ * Copyright (C) 2022 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
+ *
+ * libsamsung-ipc 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libsamsung-ipc 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 libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+
+#include <curl/curl.h>
+
+/* CURL documentation for curl_easy_escape[1] mentions that "This
+ * function does not accept input strings longer than
+ * CURL_MAX_INPUT_LENGTH (8 MB)." but CURL_MAX_INPUT_LENGTH is not
+ * exported in the curl public headers (in /usr/include/curl).
+ */
+#define CURL_MAX_INPUT_LENGTH 8000000
+
+long send_https(CURL *hnd, char *url, __attribute__((unused)) char *post_data)
+{
+ CURLcode ret;
+ long return_code;
+
+ curl_easy_setopt(hnd, CURLOPT_BUFFERSIZE, 102400L);
+ curl_easy_setopt(hnd, CURLOPT_URL, url);
+ curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L);
+ curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
+ curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION,
+ (long)CURL_HTTP_VERSION_2TLS);
+ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
+ curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
+
+ ret = curl_easy_perform(hnd);
+ assert(ret == CURLE_OK);
+
+ curl_easy_getinfo(hnd, CURLINFO_RESPONSE_CODE, &return_code);
+
+ return return_code;
+}
+
+int create_parameter(CURL *hnd,
+ char **out, const char *parameter, const char *value)
+{
+ char *result = NULL;
+ char *encoded_value;
+ size_t size = 0;
+ size_t rc;
+
+ assert(strlen(value) < CURL_MAX_INPUT_LENGTH);
+ encoded_value = curl_easy_escape(hnd, value, 0);
+ assert(encoded_value != NULL);
+
+ rc = snprintf(result, size, "%s=%s", parameter, encoded_value);
+
+ assert(rc > 0);
+ size = rc;
+
+ result = malloc(size + 1);
+ if (result == NULL) {
+ rc = -errno;
+ printf("%s: error %zd: %s\n", __func__, rc, strerror(rc));
+ return rc;
+ }
+
+ rc = snprintf(result, size + 1, "%s=%s", parameter, encoded_value);
+ assert(rc == size);
+
+ assert(rc < CURL_MAX_INPUT_LENGTH);
+
+ *out = result;
+
+ curl_free(encoded_value);
+
+ return 0;
+}
+
+int send_sms_get(const char *username, const char *password,
+ const char *message)
+{
+ CURL *hnd;
+ char *parameter = NULL;
+ int rc;
+ CURLU *url;
+ char *url_string;
+
+ url = curl_url();
+ hnd = curl_easy_init();
+
+ rc = curl_url_set(url, CURLUPART_URL,
+ "https://smsapi.free-mobile.fr/sendmsg", 0);
+ assert(rc == 0);
+
+ rc = create_parameter(hnd, &parameter, "user", username);
+ assert(rc == 0);
+ rc = curl_url_set(url, CURLUPART_QUERY, parameter, CURLU_APPENDQUERY);
+ assert(rc == 0);
+ free(parameter);
+
+ rc = create_parameter(hnd, &parameter, "pass", password);
+ rc = curl_url_set(url, CURLUPART_QUERY, parameter, CURLU_APPENDQUERY);
+ assert(rc == 0);
+ free(parameter);
+
+ rc = create_parameter(hnd, &parameter, "msg", message);
+ rc = curl_url_set(url, CURLUPART_QUERY, parameter, CURLU_APPENDQUERY);
+ assert(rc == 0);
+ free(parameter);
+
+ rc = curl_url_get(url, CURLUPART_URL, &url_string, 0);
+ assert(rc == 0);
+
+ rc = send_https(hnd, url_string, NULL);
+
+ switch (rc) {
+ case 200:
+ /* SMS SENT */
+ rc = 0;
+ break;
+ case 400:
+ printf("Error %d: %s\n",
+ rc,
+ "Missing parameter (user, login, message).");
+ rc = EX_USAGE;
+ break;
+ case 402:
+ printf("Error %d: %s\n",
+ rc,
+ "Too many SMS sent in too little time: Retry later.\n");
+ rc = EX_TEMPFAIL;
+ break;
+ case 403:
+ printf("Error %d: %s\n",
+ rc,
+ "Possible causes:\n"
+ "- Service is not enabled in your account settings.\n"
+ "- Wrong login or password.\n");
+ rc = EX_CONFIG;
+ break;
+ case 500:
+ printf("Error %d: %s\n",
+ rc,
+ "Service unavailable: Retry later");
+ rc = EX_UNAVAILABLE;
+ break;
+ default:
+ printf("Unknown error %d.\n", rc);
+ rc = EX_PROTOCOL;
+ break;
+ }
+
+ curl_easy_cleanup(hnd);
+ curl_url_cleanup(url);
+
+ return rc;
+}
+
+void usage(char *progname)
+{
+ printf("Usage: %s free-mobile <username> <token> <message>\n\n",
+ progname);
+ printf("Example:\n\t%s %s \"%s\" \"%s\" \"%s\"\n",
+ progname,
+ "free-mobile",
+ "12345678",
+ "1234abcdEFGH",
+ "hello world!");
+}
+
+int main(int argc, char *argv[])
+{
+ char *message;
+ char *password;
+ char *username;
+ int rc;
+
+ if (argc != 5 || strncmp("free-mobile", argv[1],
+ strlen("free-mobile"))) {
+ usage(argv[0]);
+ return EX_USAGE;
+ }
+
+ username = argv[2];
+ password = argv[3];
+ message = argv[4];
+
+ rc = send_sms_get(username, password, message);
+ if (rc == 0)
+ printf("OK\n");
+ return rc;
+}
diff --git a/tools/ipc-modem.c b/tools/ipc-modem.c
deleted file mode 100644
index cc53749..0000000
--- a/tools/ipc-modem.c
+++ /dev/null
@@ -1,607 +0,0 @@
-/*
- * This file is part of libsamsung-ipc.
- *
- * Copyright (C) 2011 Simon Busch <morphis@gravedo.de>
- * Copyright (C) 2011 Paul Kocialkowsk <contact@paulk.fr>
- *
- * libsamsung-ipc 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 2 of the License, or
- * (at your option) any later version.
- *
- * libsamsung-ipc 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 libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <assert.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <pthread.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <termios.h>
-#include <unistd.h>
-#include <string.h>
-
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <samsung-ipc.h>
-
-#define MODEM_STATE_LPM 0
-#define MODEM_STATE_NORMAL 2
-#define MODEM_STATE_SIM_OK 4
-
-int state = MODEM_STATE_LPM;
-int seq;
-int in_call;
-int out_call;
-int call_done;
-
-char call_number[14];
-char sim_pin[8];
-
-int seq_get(void)
-{
- if (seq == 0xff)
- seq = 0x00;
-
- seq++;
-
- return seq;
-}
-
-void modem_snd_no_mic_mute(struct ipc_client *client)
-{
- uint8_t data = 0;
-
- ipc_client_send(client, seq_get(), IPC_SND_MIC_MUTE_CTRL, IPC_TYPE_SET,
- (void *) &data, 1);
-}
-
-void modem_snd_clock_ctrl(struct ipc_client *client)
-{
- uint8_t data = 0x01;
-
- ipc_client_send(client, seq_get(), IPC_SND_CLOCK_CTRL, IPC_TYPE_EXEC,
- (void *) &data, 1);
-}
-
-void modem_snd_spkr_volume_ctrl(struct ipc_client *client)
-{
- uint16_t data = 0x0411;
-
- ipc_client_send(client, seq_get(), IPC_SND_SPKR_VOLUME_CTRL,
- IPC_TYPE_SET, (void *) &data, 2);
-}
-
-void modem_snd_audio_path_ctrl(struct ipc_client *client)
-{
- uint8_t data = 0x01;
-
- ipc_client_send(client, seq_get(), IPC_SND_AUDIO_PATH_CTRL,
- IPC_TYPE_SET, (void *) &data, 1);
-}
-
-
-
-void modem_exec_call_out(struct ipc_client *client, char *num)
-{
- struct ipc_call_outgoing_data call_out;
-
- modem_snd_no_mic_mute(client);
-
- memset(&call_out, 0, sizeof(struct ipc_call_outgoing_data));
-
- call_out.type = IPC_CALL_TYPE_VOICE;
- call_out.identity = IPC_CALL_IDENTITY_DEFAULT;
- call_out.number_length = strlen(num);
- /* TODO: Add support for prefixes */
- /* 0x21 = +33 */
- call_out.prefix = IPC_CALL_PREFIX_NONE; //0x21;//IPC_CALL_PREFIX_NONE;
- memcpy(call_out.number, num, call_out.number_length);
-
- ipc_client_send(client, seq_get(), IPC_CALL_OUTGOING, IPC_TYPE_EXEC,
- (void *) &call_out,
- sizeof(struct ipc_call_outgoing_data));
-
- out_call = 1;
-
- modem_snd_no_mic_mute(client);
- modem_snd_spkr_volume_ctrl(client);
- modem_snd_audio_path_ctrl(client);
-}
-
-void modem_exec_call_answer(struct ipc_client *client)
-{
- modem_snd_clock_ctrl(client);
-
- ipc_client_send(client, seq_get(), IPC_CALL_ANSWER, IPC_TYPE_EXEC, NULL,
- 0);
-
- modem_snd_no_mic_mute(client);
-}
-
-void modem_get_call_list(struct ipc_client *client)
-{
- ipc_client_send(client, seq_get(), IPC_CALL_LIST, IPC_TYPE_GET, NULL,
- 0);
-
- modem_snd_no_mic_mute(client);
-}
-
-void modem_exec_power_normal(struct ipc_client *client)
-{
- uint16_t data = 0x0202;
-
- ipc_client_send(client, seq_get(), IPC_PWR_PHONE_STATE, IPC_TYPE_EXEC,
- (void *) &data, sizeof(data));
-}
-
-void modem_set_sms_device_ready(struct ipc_client *client)
-{
- ipc_client_send(client, seq_get(), IPC_SMS_DEVICE_READY, IPC_TYPE_SET,
- NULL, 0);
-}
-
-void modem_set_sec_pin_status(struct ipc_client *client, char *pin1, char *pin2)
-{
- struct ipc_sec_pin_status_request_data pin_status;
-
- printf("[I] Sending PIN1 unlock request\n");
-
- ipc_sec_pin_status_setup(&pin_status, IPC_SEC_PIN_TYPE_PIN1, pin1,
- pin2);
-
- ipc_client_send(client, seq_get(), IPC_SEC_PIN_STATUS, IPC_TYPE_SET,
- (void *) &pin_status, sizeof(pin_status));
-}
-
-void modem_response_sec(struct ipc_client *client, struct ipc_message *resp)
-{
- struct ipc_sec_pin_status_response_data *sim_status;
- unsigned char type;
-
- switch (resp->command) {
- case IPC_SEC_PIN_STATUS:
- sim_status =
- (struct ipc_sec_pin_status_response_data *)resp->data;
-
- switch (sim_status->status) {
- case IPC_SEC_PIN_STATUS_CARD_NOT_PRESENT:
- printf("[I] SIM card is definitely absent\n");
- break;
- case IPC_SEC_PIN_STATUS_LOCK_SC:
- switch (sim_status->facility_lock) {
- case IPC_SEC_FACILITY_LOCK_TYPE_SC_PIN1_REQ:
- printf("[I] "
- "We need the PIN1 to unlock the card!"
- "\n");
- if (strlen(sim_pin) > 0) {
- modem_set_sec_pin_status(client,
- sim_pin, NULL);
- } else {
- printf("[E] No SIM Pin, use --pin\n");
- }
- break;
- case IPC_SEC_FACILITY_LOCK_TYPE_SC_PUK_REQ:
- printf("[I] Please provide the SIM card PUK!"
- "\n");
- break;
- case IPC_SEC_FACILITY_LOCK_TYPE_SC_CARD_BLOCKED:
- printf("[I] Ouch, the SIM Card is blocked.\n");
- break;
- }
- break;
- case IPC_SEC_PIN_STATUS_INIT_COMPLETE:
- printf("[3] SIM init complete\n");
- if (state == MODEM_STATE_NORMAL)
- state = MODEM_STATE_SIM_OK;
- break;
- case IPC_SEC_PIN_STATUS_PB_INIT_COMPLETE:
- printf("[I] SIM Phone Book init complete\n");
- break;
- }
- break;
- case IPC_SEC_SIM_ICC_TYPE:
- type = *((char *) resp->data);
- switch (type) {
- case IPC_SEC_SIM_CARD_TYPE_UNKNOWN:
- printf("[I] No SIM card type: unknown (absent?)\n");
- break;
- case IPC_SEC_SIM_CARD_TYPE_SIM:
- case IPC_SEC_SIM_CARD_TYPE_USIM:
- printf("[I] SIM card found\n");
- break;
- }
- break;
- }
-}
-
-void modem_response_sms(struct ipc_client *client, struct ipc_message *resp)
-{
- switch (resp->command) {
- case IPC_SMS_DEVICE_READY:
- if (state == MODEM_STATE_LPM) {
- printf("[4] "
- "Modem is ready, requesting normal power mode"
- "\n");
- modem_exec_power_normal(client);
- } else if (state == MODEM_STATE_SIM_OK) {
- printf("[5] Modem is fully ready\n");
- modem_set_sms_device_ready(client);
- }
- break;
- }
-}
-
-void modem_response_call(struct ipc_client *client, struct ipc_message *resp)
-{
- struct ipc_call_status_data *stat;
-
- switch (resp->command) {
- case IPC_CALL_LIST:
- /*
- * if (in_call)
- * modem_exec_call_answer(client);
- * if (out_call)
- * modem_snd_no_mic_mute(client);
- */
- break;
- case IPC_CALL_INCOMING:
- printf("[I] Got an incoming call!\n");
- in_call = 1;
- modem_get_call_list(client);
- break;
- case IPC_CALL_STATUS:
- stat = (struct ipc_call_status_data *)resp->data;
-
- if (stat->status == IPC_CALL_STATUS_DIALING) {
- printf("[I] Sending clock ctrl and restore alsa\n");
- modem_snd_clock_ctrl(client);
- /*
- * system("alsa_ctl -f /data/alsa_state_modem restore");
- */
-
- printf("[I] CALL STATUS DIALING!!!\n");
-
- modem_snd_spkr_volume_ctrl(client);
- modem_snd_audio_path_ctrl(client);
-
- modem_get_call_list(client);
- }
-
- if (stat->status == IPC_CALL_STATUS_CONNECTED) {
- printf("[I] CALL STATUS CONNECTED!!!\n");
- modem_snd_no_mic_mute(client);
- }
-
- if (stat->status == IPC_CALL_STATUS_RELEASED) {
- printf("[I] CALL STATUS RELEASED!!!\n");
- modem_snd_no_mic_mute(client);
- }
- break;
- }
-}
-
-void modem_response_pwr(__attribute__((unused)) struct ipc_client *client,
- struct ipc_message *resp)
-{
- int state_n;
-
- switch (resp->command) {
- case IPC_PWR_PHONE_PWR_UP:
- printf("[2] Phone is powered up (LPM)!\n");
- state = MODEM_STATE_LPM;
- break;
-
- case IPC_PWR_PHONE_STATE:
- state_n = *((int *)resp->data);
-#if 0
- switch (state_n) {
- /* FIXME: Broken */
- case IPC_PWR_PHONE_STATE_NORMAL:
- printf("Power state is now: NORMAL\n");
- break;
- case IPC_PWR_PHONE_STATE_LPM:
- printf("Power state is now: LPM (Low Power Mode)?\n");
- break;
- }
-#endif
- state = state_n;
- break;
-
- }
-}
-
-void modem_response_net(__attribute__((unused)) struct ipc_client *client,
- struct ipc_message *resp)
-{
- struct ipc_net_regist_response_data *regi;
- char mnc[6];
-
- switch (resp->command) {
- case IPC_NET_REGIST:
- regi = (struct ipc_net_regist_response_data *) resp->data;
- if (regi->status == IPC_NET_REGISTRATION_STATUS_HOME)
- printf("[I] Registered with network successfully!\n");
- break;
- case IPC_NET_SERVING_NETWORK:
- memcpy(mnc, (char *)((char *) resp->data + 3), 5);
- mnc[5] = 0;
- printf("[6] Registered with network! "
- "Got PLMN (Mobile Network Code): '%s'\n",
- mnc);
- if (call_done == 0) {
- printf("Requesting outgoing call to %s!\n",
- call_number);
- modem_exec_call_out(client, call_number);
- }
- call_done = 1;
- break;
- }
-}
-
-void modem_response_handle(struct ipc_client *client, struct ipc_message *resp)
-{
- switch (IPC_GROUP(resp->command)) {
- case IPC_GROUP_NET:
- modem_response_net(client, resp);
- break;
- case IPC_GROUP_PWR:
- modem_response_pwr(client, resp);
- break;
- case IPC_GROUP_SEC:
- modem_response_sec(client, resp);
- break;
- case IPC_GROUP_SMS:
- modem_response_sms(client, resp);
- break;
- case IPC_GROUP_CALL:
- modem_response_call(client, resp);
- break;
- case IPC_GROUP_DISP:
- if (in_call)
- modem_snd_no_mic_mute(client);
- break;
- }
-}
-
-
-int modem_read_loop(struct ipc_client *client)
-{
- struct ipc_message resp;
- int rc;
-
- memset(&resp, 0, sizeof(resp));
-
- while (1) {
- usleep(3000);
-
- rc = ipc_client_poll(client, NULL, NULL);
- if (rc < 0)
- continue;
-
- rc = ipc_client_recv(client, &resp);
- if (rc < 0) {
- printf("[E] "
- "Can't RECV from modem: please run this again"
- "\n");
- break;
- }
-
- modem_response_handle(client, &resp);
-
- if (resp.data != NULL)
- free(resp.data);
- }
-
- return 0;
-}
-
-void modem_log_handler(__attribute__((unused)) void *user_data,
- const char *msg)
-{
- int i, l;
- char *message;
-
- message = strdup(msg);
- l = strlen(message);
-
- if (l > 1) {
- for (i = l ; i > 0 ; i--) {
- if (message[i] == '\n')
- message[i] = 0;
- else if (message[i] != 0)
- break;
- }
-
- printf("[D] %s\n", message);
- }
-
- free(message);
-}
-
-void modem_log_handler_quiet(__attribute__((unused)) void *user_data,
- __attribute__((unused)) const char *msg)
-{
-}
-
-int modem_start(struct ipc_client *client)
-{
- int rc = -1;
-
- ipc_client_data_create(client);
- rc = ipc_client_boot(client);
- if (rc < 0)
- return -1;
-
- usleep(300);
-
- rc = ipc_client_open(client);
- if (rc < 0)
- return -1;
-
- rc = ipc_client_power_on(client);
- if (rc < 0)
- return -1;
-
- return 0;
-}
-
-int modem_stop(struct ipc_client *client)
-{
- ipc_client_power_off(client);
- ipc_client_close(client);
-
- return 0;
-}
-
-void print_help(void)
-{
- printf("usage: ipc-modem <command>\n");
- printf("commands:\n");
- printf("\tstart boot modem and start read loop\n");
- printf("\tboot boot modem only\n");
- printf("\tpower-on power on the modem\n");
- printf("\tpower-off power off the modem\n");
- printf("arguments:\n");
- printf("\t--debug enable debug messages\n");
- printf("\t--pin=[PIN] provide SIM card PIN\n");
- printf("\t--call=[NUMBER] call NUMBER\n");
-}
-
-int main(int argc, char *argv[])
-{
- struct ipc_client *client_fmt;
- int c = 0;
- int opt_i = 0;
- int rc = -1;
- int debug = 0;
-
- struct option opt_l[] = {
- {"help", no_argument, 0, 0 },
- {"debug", no_argument, 0, 0 },
- {"pin", required_argument, 0, 0 },
- {"call", required_argument, 0, 0 },
- {0, 0, 0, 0 }
- };
-
- if (argc < 2) {
- print_help();
- exit(1);
- }
-
- while (c >= 0) {
- c = getopt_long(argc, argv, "", opt_l, &opt_i);
- if (c < 0)
- break;
-
- switch (c) {
- case 0:
- if (strncmp(opt_l[opt_i].name, "help", 4) == 0) {
- print_help();
- exit(1);
- } else if (strcmp(opt_l[opt_i].name, "debug") == 0) {
- debug = 1;
- printf("[I] Debug enabled\n");
- } else if ((strcmp(opt_l[opt_i].name, "pin") == 0) &&
- (optarg)) {
- if (strlen(optarg) < 8) {
- assert(strlen(optarg) <
- sizeof(sim_pin));
-
- printf("[I] Got SIM PIN!\n");
- strcpy(sim_pin, optarg);
- } else {
- printf("[E] SIM PIN is too long!\n");
- return 1;
- }
- } else if (strcmp(opt_l[opt_i].name, "call") == 0) {
- if (optarg) {
- if (strlen(optarg) < 14) {
- assert(strlen(optarg) <
- sizeof(call_number));
- printf("[I] "
- "Got call number!\n");
- strcpy(call_number, optarg);
- } else {
- printf("[E] "
- "Call number is too long!"
- "\n");
- return 1;
- }
- }
- }
-
- break;
- }
- }
-
- client_fmt = ipc_client_create(IPC_CLIENT_TYPE_FMT);
-
- if (client_fmt == 0) {
- printf("[E] Could not create IPC client; aborting ...\n");
- goto modem_quit;
- }
-
- if (debug == 0) {
- ipc_client_log_callback_register(client_fmt,
- modem_log_handler_quiet, NULL);
- } else {
- ipc_client_log_callback_register(client_fmt, modem_log_handler,
- NULL);
- }
-
- while (optind < argc) {
- if (strncmp(argv[optind], "power-on", 8) == 0) {
- if (ipc_client_power_on(client_fmt) < 0)
- printf("[E] Something went wrong "
- "while powering modem on\n");
- goto modem_quit;
- } else if (strncmp(argv[optind], "power-off", 9) == 0) {
- if (ipc_client_power_off(client_fmt) < 0)
- printf("[E] Something went wrong "
- "while powering modem off\n");
- goto modem_quit;
- } else if (strncmp(argv[optind], "boot", 9) == 0) {
- rc = ipc_client_boot(client_fmt);
- if (rc < 0)
- printf("[E] Something went wrong "
- "while bootstrapping modem\n");
- } else if (strncmp(argv[optind], "start", 5) == 0) {
- printf("[0] Starting modem on FMT client\n");
- rc = modem_start(client_fmt);
- if (rc < 0) {
- printf("[E] Something went wrong\n");
- modem_stop(client_fmt);
- return 1;
- }
-
- printf("[1] Starting modem_read_loop on FMT client\n");
- modem_read_loop(client_fmt);
-
- modem_stop(client_fmt);
- } else {
- printf("[E] Unknown argument: '%s'\n", argv[optind]);
- print_help();
- return 1;
- }
-
- optind++;
- }
-
-modem_quit:
- if (client_fmt != 0)
- ipc_client_destroy(client_fmt);
-
- return 0;
-}
diff --git a/tools/ipc-modem/Makefile.am b/tools/ipc-modem/Makefile.am
new file mode 100644
index 0000000..64cde49
--- /dev/null
+++ b/tools/ipc-modem/Makefile.am
@@ -0,0 +1,28 @@
+NULL =
+EXTRA_DIST = $(NULL)
+
+AM_CFLAGS = \
+ -I$(top_srcdir)/include \
+ $(NULL)
+
+if WANT_STRICT_CFLAGS
+AM_CFLAGS += $(STRICT_CFLAGS)
+endif
+
+bin_PROGRAMS = ipc-modem
+
+# TODO: Find a way to make test more modular and represent each run of the
+# ipc-modem in TEST while having it implemented in a single python file
+PY_LOG_COMPILER = $(PYTHON3)
+TEST_EXTENSIONS = .py
+TESTS = tests/ipc-modem.py
+EXTRA_DIST += $(TESTS)
+
+ipc_modem_SOURCES = \
+ipc-modem.c \
+ipc-modem.h \
+ipc-modem-log.c \
+ipc-modem-log.h
+
+ipc_modem_LDADD = $(top_builddir)/samsung-ipc/libsamsung-ipc.la
+ipc_modem_LDFLAGS = -lpthread $(ALL_STATIC_LDFLAGS)
diff --git a/tools/ipc-modem/ipc-modem-log.c b/tools/ipc-modem/ipc-modem-log.c
new file mode 100644
index 0000000..7e6b48d
--- /dev/null
+++ b/tools/ipc-modem/ipc-modem-log.c
@@ -0,0 +1,84 @@
+/*
+ * This file is part of libsamsung-ipc.
+ *
+ * Copyright (C) 2011 Simon Busch <morphis@gravedo.de>
+ * Copyright (C) 2011 Paul Kocialkowsk <contact@paulk.fr>
+ * Copyright (C) 2022 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
+ *
+ * libsamsung-ipc 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libsamsung-ipc 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 libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+
+#include "ipc-modem-log.h"
+
+static enum log_target log_target;
+
+void modem_log_handler(void *user_data, const char *msg)
+{
+ int i, l;
+ char *message;
+
+ message = strdup(msg);
+ l = strlen(message);
+
+ if (l > 1) {
+ for (i = l ; i > 0 ; i--) {
+ if (message[i] == '\n')
+ message[i] = 0;
+ else if (message[i] != 0)
+ break;
+ }
+
+ if (log_target == LOG_TO_STDOUT && user_data)
+ printf("[%s] %s\n", (char *)user_data, message);
+ else if (log_target == LOG_TO_STDOUT)
+ printf("[%s] %s\n", MODEM_LOG_DEBUG, message);
+ else if (log_target == LOG_TO_SYSLOG && user_data)
+ syslog(LOG_INFO,
+ "[%s] %s\n", (char *)user_data, message);
+ else if (log_target == LOG_TO_SYSLOG)
+ syslog(LOG_INFO, "[%s] %s\n", MODEM_LOG_DEBUG, message);
+ }
+
+ free(message);
+}
+
+void modem_log_handler_quiet(__attribute__((unused)) void *user_data,
+ __attribute__((unused)) const char *msg)
+{
+}
+
+void ipc_modem_log(__attribute__((unused)) struct ipc_client *client,
+ char *prefix, const char *message, ...)
+{
+ va_list args;
+ char buffer[4096];
+
+ va_start(args, message);
+ vsnprintf((char *) &buffer, sizeof(buffer), message, args);
+ va_end(args);
+
+ modem_log_handler(prefix, buffer);
+}
+
+void ipc_modem_set_log_target(enum log_target target)
+{
+ log_target = target;
+}
+
diff --git a/tools/ipc-modem/ipc-modem-log.h b/tools/ipc-modem/ipc-modem-log.h
new file mode 100644
index 0000000..1786295
--- /dev/null
+++ b/tools/ipc-modem/ipc-modem-log.h
@@ -0,0 +1,41 @@
+/*
+ * This file is part of libsamsung-ipc.
+ *
+ * Copyright (C) 2022 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
+ *
+ * libsamsung-ipc 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libsamsung-ipc 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 libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef IPC_MODEM_LOG_H
+#define IPC_MODEM_LOG_H
+
+#include <stdarg.h>
+
+#include <samsung-ipc.h>
+
+#define MODEM_LOG_ERROR "E"
+#define MODEM_LOG_INFO "I"
+#define MODEM_LOG_DEBUG "D"
+
+enum log_target {
+ LOG_TO_STDOUT,
+ LOG_TO_SYSLOG,
+};
+
+void ipc_modem_log(struct ipc_client *client,
+ char *prefix, const char *message, ...);
+void modem_log_handler(void *user_data, const char *msg);
+void modem_log_handler_quiet(void *user_data, const char *msg);
+void ipc_modem_set_log_target(enum log_target target);
+
+#endif /* IPC_MODEM_LOG_H */
diff --git a/tools/ipc-modem/ipc-modem.c b/tools/ipc-modem/ipc-modem.c
new file mode 100644
index 0000000..c70bcc1
--- /dev/null
+++ b/tools/ipc-modem/ipc-modem.c
@@ -0,0 +1,781 @@
+/*
+ * This file is part of libsamsung-ipc.
+ *
+ * Copyright (C) 2011 Simon Busch <morphis@gravedo.de>
+ * Copyright (C) 2011 Paul Kocialkowsk <contact@paulk.fr>
+ *
+ * libsamsung-ipc 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libsamsung-ipc 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 libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <assert.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <sysexits.h>
+#include <termios.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <samsung-ipc.h>
+
+#include "ipc-modem.h"
+#include "ipc-modem-log.h"
+
+int seq_get(struct ipc_modem_data *data)
+{
+ if (data->seq == 0xff)
+ data->seq = 0x00;
+
+ data->seq++;
+
+ return data->seq;
+}
+
+void modem_snd_no_mic_mute(struct ipc_modem_data *data)
+{
+ uint8_t mic_mute_data = 0;
+
+ ipc_client_send(data->client,
+ seq_get(data), IPC_SND_MIC_MUTE_CTRL, IPC_TYPE_SET,
+ (void *) &mic_mute_data, 1);
+}
+
+void modem_snd_clock_ctrl(struct ipc_modem_data *data)
+{
+ uint8_t clock_ctrl_data = 0x01;
+
+ ipc_client_send(data->client,
+ seq_get(data), IPC_SND_CLOCK_CTRL, IPC_TYPE_EXEC,
+ (void *) &clock_ctrl_data, 1);
+}
+
+void modem_snd_spkr_volume_ctrl(struct ipc_modem_data *data)
+{
+ uint16_t spkr_volume_data = 0x0411;
+
+ ipc_client_send(data->client, seq_get(data), IPC_SND_SPKR_VOLUME_CTRL,
+ IPC_TYPE_SET, (void *) &spkr_volume_data, 2);
+}
+
+void modem_snd_audio_path_ctrl(struct ipc_modem_data *data)
+{
+ uint8_t audio_path_ctrl_data = 0x01;
+
+ ipc_client_send(data->client, seq_get(data), IPC_SND_AUDIO_PATH_CTRL,
+ IPC_TYPE_SET, (void *) &audio_path_ctrl_data, 1);
+}
+
+
+
+void modem_exec_call_out(struct ipc_modem_data *data, char *num)
+{
+ struct ipc_call_outgoing_data call_out;
+
+ modem_snd_no_mic_mute(data);
+
+ memset(&call_out, 0, sizeof(struct ipc_call_outgoing_data));
+
+ call_out.type = IPC_CALL_TYPE_VOICE;
+ call_out.identity = IPC_CALL_IDENTITY_DEFAULT;
+ call_out.number_length = strlen(num);
+ /* TODO: Add support for prefixes */
+ /* 0x21 = +33 */
+ call_out.prefix = IPC_CALL_PREFIX_NONE; //0x21;//IPC_CALL_PREFIX_NONE;
+ memcpy(call_out.number, num, call_out.number_length);
+
+ ipc_client_send(data->client,
+ seq_get(data), IPC_CALL_OUTGOING, IPC_TYPE_EXEC,
+ (void *) &call_out,
+ sizeof(struct ipc_call_outgoing_data));
+
+ data->out_call = 1;
+
+ modem_snd_no_mic_mute(data);
+ modem_snd_spkr_volume_ctrl(data);
+ modem_snd_audio_path_ctrl(data);
+}
+
+void modem_exec_call_answer(struct ipc_modem_data *data)
+{
+ modem_snd_clock_ctrl(data);
+
+ ipc_client_send(data->client,
+ seq_get(data), IPC_CALL_ANSWER, IPC_TYPE_EXEC, NULL, 0);
+
+ modem_snd_no_mic_mute(data);
+}
+
+void modem_get_call_list(struct ipc_modem_data *data)
+{
+ ipc_client_send(data->client,
+ seq_get(data), IPC_CALL_LIST, IPC_TYPE_GET, NULL, 0);
+
+ modem_snd_no_mic_mute(data);
+}
+
+void modem_exec_power_normal(struct ipc_modem_data *data)
+{
+ uint16_t exec_data = IPC_PWR_PHONE_STATE_REQUEST_NORMAL;
+
+ ipc_client_send(data->client,
+ seq_get(data), IPC_PWR_PHONE_STATE, IPC_TYPE_EXEC,
+ (void *) &exec_data, sizeof(data));
+}
+
+void modem_set_sms_device_ready(struct ipc_modem_data *data)
+{
+ ipc_client_send(data->client,
+ seq_get(data), IPC_SMS_DEVICE_READY, IPC_TYPE_SET,
+ NULL, 0);
+}
+
+void modem_set_sec_pin_status(struct ipc_modem_data *data,
+ char *pin1, char *pin2)
+{
+ struct ipc_sec_pin_status_request_data pin_status;
+
+ ipc_modem_log(data->client,
+ MODEM_LOG_INFO, "Sending PIN1 unlock request\n");
+
+ ipc_sec_pin_status_setup(&pin_status, IPC_SEC_PIN_TYPE_PIN1, pin1,
+ pin2);
+
+ ipc_client_send(data->client,
+ seq_get(data), IPC_SEC_PIN_STATUS, IPC_TYPE_SET,
+ (void *) &pin_status, sizeof(pin_status));
+}
+
+void modem_response_sec(struct ipc_modem_data *data, struct ipc_message *resp)
+{
+ struct ipc_sec_pin_status_response_data *sim_status;
+ unsigned char type;
+
+ switch (resp->command) {
+ case IPC_SEC_PIN_STATUS:
+ sim_status =
+ (struct ipc_sec_pin_status_response_data *)resp->data;
+
+ switch (sim_status->status) {
+ case IPC_SEC_PIN_STATUS_CARD_NOT_PRESENT:
+ ipc_modem_log(data->client, MODEM_LOG_INFO,
+ "SIM card is definitely absent\n");
+ break;
+ case IPC_SEC_PIN_STATUS_LOCK_SC:
+ switch (sim_status->facility_lock) {
+ case IPC_SEC_FACILITY_LOCK_TYPE_SC_PIN1_REQ:
+ ipc_modem_log(
+ data->client,
+ MODEM_LOG_INFO,
+ "We need the PIN1 to unlock the card!"
+ "\n");
+ if (strlen(data->sim_pin) > 0) {
+ modem_set_sec_pin_status(data,
+ data->sim_pin,
+ NULL);
+ } else {
+ ipc_modem_log(
+ data->client,
+ MODEM_LOG_ERROR,
+ "No SIM Pin, use --pin\n");
+ }
+ break;
+ case IPC_SEC_FACILITY_LOCK_TYPE_SC_PUK_REQ:
+ ipc_modem_log(
+ data->client,
+ MODEM_LOG_INFO,
+ "Please provide the SIM card PUK!"
+ "\n");
+ break;
+ case IPC_SEC_FACILITY_LOCK_TYPE_SC_CARD_BLOCKED:
+ ipc_modem_log(
+ data->client,
+ MODEM_LOG_INFO,
+ "Ouch, the SIM Card is blocked.\n");
+ break;
+ }
+ break;
+ case IPC_SEC_PIN_STATUS_INIT_COMPLETE:
+ ipc_modem_log(data->client, "3", "SIM init complete\n");
+ if (data->state == MODEM_STATE_NORMAL)
+ data->state = MODEM_STATE_SIM_OK;
+ break;
+ case IPC_SEC_PIN_STATUS_PB_INIT_COMPLETE:
+ ipc_modem_log(data->client,
+ MODEM_LOG_INFO,
+ "SIM Phone Book init complete\n");
+ break;
+ }
+ break;
+ case IPC_SEC_SIM_ICC_TYPE:
+ type = *((char *) resp->data);
+ switch (type) {
+ case IPC_SEC_SIM_CARD_TYPE_UNKNOWN:
+ ipc_modem_log(
+ data->client,
+ MODEM_LOG_INFO,
+ "No SIM card type: unknown (absent?)\n");
+ break;
+ case IPC_SEC_SIM_CARD_TYPE_SIM:
+ case IPC_SEC_SIM_CARD_TYPE_USIM:
+ ipc_modem_log(data->client,
+ MODEM_LOG_INFO, "SIM card found\n");
+ break;
+ }
+ break;
+ }
+}
+
+void modem_response_sms(struct ipc_modem_data *data, struct ipc_message *resp)
+{
+ switch (resp->command) {
+ case IPC_SMS_DEVICE_READY:
+ if (data->state == MODEM_STATE_LPM) {
+ ipc_modem_log(
+ data->client,
+ "4",
+ "Modem is ready, requesting normal power mode"
+ "\n");
+ modem_exec_power_normal(data);
+ } else if (data->state == MODEM_STATE_SIM_OK) {
+ ipc_modem_log(data->client,
+ "5", "Modem is fully ready\n");
+ modem_set_sms_device_ready(data);
+ }
+ break;
+ }
+}
+
+void modem_response_call(struct ipc_modem_data *data, struct ipc_message *resp)
+{
+ struct ipc_call_status_data *stat;
+
+ switch (resp->command) {
+ case IPC_CALL_LIST:
+ /*
+ * if (data->in_call)
+ * modem_exec_call_answer(data->client);
+ * if (data->out_call)
+ * modem_snd_no_mic_mute(data);
+ */
+ break;
+ case IPC_CALL_INCOMING:
+ ipc_modem_log(data->client,
+ MODEM_LOG_INFO, "Got an incoming call!\n");
+ data->in_call = 1;
+ modem_get_call_list(data);
+ break;
+ case IPC_CALL_STATUS:
+ stat = (struct ipc_call_status_data *)resp->data;
+
+ if (stat->status == IPC_CALL_STATUS_DIALING) {
+ ipc_modem_log(
+ data->client,
+ MODEM_LOG_INFO,
+ "Sending clock ctrl and restore alsa\n");
+ modem_snd_clock_ctrl(data);
+ /*
+ * system("alsa_ctl -f /data/alsa_state_modem restore");
+ */
+
+ ipc_modem_log(data->client,
+ MODEM_LOG_INFO,
+ "CALL STATUS DIALING!!!\n");
+
+ modem_snd_spkr_volume_ctrl(data);
+ modem_snd_audio_path_ctrl(data);
+
+ modem_get_call_list(data);
+ }
+
+ if (stat->status == IPC_CALL_STATUS_CONNECTED) {
+ ipc_modem_log(data->client,
+ MODEM_LOG_INFO,
+ "CALL STATUS CONNECTED!!!\n");
+ modem_snd_no_mic_mute(data);
+ }
+
+ if (stat->status == IPC_CALL_STATUS_RELEASED) {
+ ipc_modem_log(data->client,
+ MODEM_LOG_INFO,
+ "CALL STATUS RELEASED!!!\n");
+ modem_snd_no_mic_mute(data);
+ }
+ break;
+ }
+}
+
+void modem_response_pwr(struct ipc_modem_data *data, struct ipc_message *resp)
+{
+ int state_n;
+
+ switch (resp->command) {
+ case IPC_PWR_PHONE_PWR_UP:
+ ipc_modem_log(data->client,
+ "2", "Phone is powered up (LPM)!\n");
+ data->state = MODEM_STATE_LPM;
+ break;
+
+ case IPC_PWR_PHONE_STATE:
+ state_n = *((int *)resp->data);
+#if 0
+ switch (state_n) {
+ /* FIXME: Broken */
+ case IPC_PWR_PHONE_STATE_NORMAL:
+ ipc_modem_log(data->client,
+ MODEM_LOG_INFO,
+ "Power state is now: NORMAL\n");
+ break;
+ case IPC_PWR_PHONE_STATE_LPM:
+ ipc_modem_log(
+ data->client,
+ MODEM_LOG_INFO,
+ "Power state is now: LPM (Low Power Mode)?\n");
+ break;
+ }
+#endif
+ data->state = state_n;
+ break;
+
+ }
+}
+
+void modem_response_net(struct ipc_modem_data *data,
+ struct ipc_message *resp)
+{
+ struct ipc_net_regist_response_data *regi;
+ char mnc[6];
+
+ switch (resp->command) {
+ case IPC_NET_REGIST:
+ regi = (struct ipc_net_regist_response_data *) resp->data;
+ if (regi->status == IPC_NET_REGISTRATION_STATUS_HOME)
+ ipc_modem_log(
+ data->client,
+ MODEM_LOG_INFO,
+ "Registered with network successfully!\n");
+ break;
+ case IPC_NET_SERVING_NETWORK:
+ memcpy(mnc, (char *)((char *) resp->data + 3), 5);
+ mnc[5] = 0;
+ ipc_modem_log(data->client,
+ "6",
+ "Registered with network! "
+ "Got PLMN (Mobile Network Code): '%s'\n",
+ mnc);
+ if (data->call_done == 0) {
+ ipc_modem_log(data->client,
+ MODEM_LOG_INFO,
+ "Requesting outgoing call to %s!\n",
+ data->call_number);
+ modem_exec_call_out(data, data->call_number);
+ }
+ data->call_done = 1;
+ break;
+ }
+}
+
+void modem_response_handle(struct ipc_modem_data *data,
+ struct ipc_message *resp)
+{
+ switch (IPC_GROUP(resp->command)) {
+ case IPC_GROUP_NET:
+ modem_response_net(data, resp);
+ break;
+ case IPC_GROUP_PWR:
+ modem_response_pwr(data, resp);
+ break;
+ case IPC_GROUP_SEC:
+ modem_response_sec(data, resp);
+ break;
+ case IPC_GROUP_SMS:
+ modem_response_sms(data, resp);
+ break;
+ case IPC_GROUP_CALL:
+ modem_response_call(data, resp);
+ break;
+ case IPC_GROUP_DISP:
+ if (data->in_call)
+ modem_snd_no_mic_mute(data);
+ break;
+ }
+}
+
+
+int modem_read_loop(struct ipc_modem_data *data)
+{
+ struct ipc_message resp;
+ int rc;
+
+ memset(&resp, 0, sizeof(resp));
+
+ while (1) {
+ usleep(3000);
+
+ rc = ipc_client_poll(data->client, NULL, NULL);
+ if (rc < 0)
+ continue;
+
+ rc = ipc_client_recv(data->client, &resp);
+ if (rc < 0) {
+ ipc_modem_log(
+ data->client,
+ MODEM_LOG_ERROR,
+ "Can't RECV from modem: please run this again"
+ "\n");
+ break;
+ }
+
+ modem_response_handle(data, &resp);
+
+ if (resp.data != NULL)
+ free(resp.data);
+ }
+
+ return 0;
+}
+
+int modem_dummy_read_loop(__attribute__((unused)) struct ipc_client *client)
+{
+ while (true) {
+ ipc_modem_log(client,
+ MODEM_LOG_INFO, "%s: looping\n", __func__);
+ sleep(1);
+ }
+
+ return 0;
+}
+
+int modem_start(struct ipc_client *client)
+{
+ int rc = -1;
+
+ ipc_client_data_create(client);
+ rc = ipc_client_boot(client);
+ if (rc < 0)
+ return -1;
+
+ usleep(300);
+
+ rc = ipc_client_open(client);
+ if (rc < 0)
+ return -1;
+
+ rc = ipc_client_power_on(client);
+ if (rc < 0)
+ return -1;
+
+ return 0;
+}
+
+int modem_stop(struct ipc_client *client)
+{
+ ipc_client_power_off(client);
+ ipc_client_close(client);
+
+ return 0;
+}
+
+void print_help(void)
+{
+ printf("usage: ipc-modem <command>\n"
+ "commands:\n"
+ "\tboot boot modem only\n"
+ "\tpower-on power on the modem only\n"
+ "\tpower-off power off the modem only\n"
+ "\tstart "
+ "boot modem and start read loop\n"
+ "arguments:\n"
+ "\t--call=<NUMBER> call NUMBER\n"
+ "\t--debug enable debug messages\n"
+ "\t--dry-run "
+ "Test the ipc-modem program without talking to the modem.\n"
+ "\t--help print this help message\n"
+ "\t--log-target=[stdout|syslog] "
+ "direct logs to stdout or syslog\n"
+ "\t--pin=<PIN> provide SIM card PIN\n");
+}
+
+int handle_command(struct ipc_modem_data *data)
+{
+ int rc = 0;
+
+ switch (data->command) {
+ case CMD_POWER_ON:
+ if (data->dry_run)
+ break;
+
+ rc = ipc_client_power_on(data->client);
+ if (rc < 0)
+ ipc_modem_log(data->client, "[E]",
+ "[E] Something went wrong "
+ "while powering modem on\n");
+ goto modem_quit;
+ case CMD_POWER_OFF:
+ if (data->dry_run)
+ break;
+
+ rc = ipc_client_power_off(data->client);
+ if (rc < 0)
+ ipc_modem_log(data->client,
+ MODEM_LOG_ERROR,
+ "Something went wrong "
+ "while powering modem off\n");
+ goto modem_quit;
+ case CMD_BOOT:
+ if (data->dry_run)
+ break;
+
+ rc = ipc_client_boot(data->client);
+ if (rc < 0)
+ ipc_modem_log(data->client,
+ MODEM_LOG_ERROR,
+ "Something went wrong "
+ "while bootstrapping modem\n");
+ break;
+ case CMD_START:
+ if (data->dry_run) {
+ ipc_modem_log(
+ data->client,
+ "1",
+ "Starting dummy modem_read_loop on %s client\n",
+ "FMT");
+ modem_dummy_read_loop(data->client);
+ break;
+ }
+
+ ipc_modem_log(data->client,
+ "0", "Starting modem on FMT client\n");
+
+ rc = modem_start(data->client);
+ if (rc < 0) {
+ ipc_modem_log(data->client,
+ MODEM_LOG_ERROR,
+ "Something went wrong\n");
+ modem_stop(data->client);
+ return EX_UNAVAILABLE;
+ }
+ ipc_modem_log(data->client,
+ "1",
+ "Starting modem_read_loop on FMT client\n");
+ modem_read_loop(data);
+
+ modem_stop(data->client);
+ break;
+ default:
+ /* We should handle all commands */
+ ipc_modem_log(data->client,
+ MODEM_LOG_ERROR,
+ "%s: Unknown command %d\n", __func__,
+ data->command);
+
+ assert(false);
+ }
+
+modem_quit:
+ if (data->client != 0)
+ ipc_client_destroy(data->client);
+
+ return rc;
+}
+
+void print_cmdline_opts(struct ipc_modem_data *data)
+
+{
+ if (data->debug)
+ ipc_modem_log(data->client, MODEM_LOG_INFO, "Debug enabled\n");
+ if (data->debug && data->dry_run)
+ ipc_modem_log(data->client, MODEM_LOG_INFO, "dry-run mode\n");
+}
+
+int parse_cmdline_opts(struct ipc_modem_data *data, int argc, char *argv[])
+{
+ int c = 0;
+ int opt_i = 0;
+
+ struct option opt_l[] = {
+ {"call", required_argument, 0, 0 },
+ {"debug", no_argument, 0, 0 },
+ {"dry-run", no_argument, 0, 0 },
+ {"help", no_argument, 0, 0 },
+ {"log-target", required_argument, 0, 0 },
+ {"pin", required_argument, 0, 0 },
+ {0, 0, 0, 0 }
+ };
+
+ if (argc < 2) {
+ print_help();
+ exit(EX_USAGE);
+ }
+
+ /* Handle options arguments */
+ while (true) {
+ c = getopt_long(argc, argv, "", opt_l, &opt_i);
+ if (c != 0)
+ break;
+
+ if (strcmp(opt_l[opt_i].name, "call") == 0) {
+ if (optarg) {
+ if (strlen(optarg) == 0) {
+ ipc_modem_log(data->client,
+ MODEM_LOG_ERROR,
+ "Missing call number\n");
+ return EX_USAGE;
+ } else if (strlen(optarg) < 14) {
+ assert(strlen(optarg) <
+ sizeof(data->call_number));
+ ipc_modem_log(data->client,
+ MODEM_LOG_INFO,
+ "Got call number!\n");
+ strcpy(data->call_number, optarg);
+ } else {
+ ipc_modem_log(
+ data->client,
+ MODEM_LOG_ERROR,
+ "Call number is too long!\n");
+ return EX_USAGE;
+ }
+ }
+ } else if ((strcmp(opt_l[opt_i].name, "log-target") == 0)) {
+ if (optarg) {
+ if (!strcmp(optarg, "syslog")) {
+ ipc_modem_set_log_target(LOG_TO_SYSLOG);
+ } else if (strcmp(optarg, "stdout")) {
+ ipc_modem_log(
+ data->client, MODEM_LOG_ERROR,
+ "Invalid log target '%s'\n",
+ optarg);
+ return EX_USAGE;
+ }
+ }
+ } else if (strcmp(opt_l[opt_i].name, "debug") == 0) {
+ data->debug = true;
+ } else if (strcmp(opt_l[opt_i].name, "dry-run") == 0) {
+ data->dry_run = true;
+ } else if (strncmp(opt_l[opt_i].name, "help", 4) == 0) {
+ print_help();
+ exit(0);
+ } else if ((strcmp(opt_l[opt_i].name, "pin") == 0) &&
+ (optarg)) {
+ if (strlen(optarg) < 8) {
+ assert(strlen(optarg) <
+ sizeof(data->sim_pin));
+
+ ipc_modem_log(
+ data->client,
+ MODEM_LOG_INFO, "Got SIM PIN!\n");
+ strcpy(data->sim_pin, optarg);
+ } else {
+ ipc_modem_log(data->client,
+ MODEM_LOG_ERROR,
+ "SIM PIN is too long!\n");
+ return EX_USAGE;
+ }
+ }
+ }
+
+ /* Handle non options arguments */
+ while (optind < argc) {
+ if (strncmp(argv[optind], "boot", 9) == 0) {
+ data->command = CMD_BOOT;
+ break;
+ } else if (strncmp(argv[optind], "power-on", 8) == 0) {
+ data->command = CMD_POWER_ON;
+ break;
+ } else if (strncmp(argv[optind], "power-off", 9) == 0) {
+ data->command = CMD_POWER_OFF;
+ break;
+ } else if (strncmp(argv[optind], "start", 5) == 0) {
+ data->command = CMD_START;
+ break;
+ } else {
+ ipc_modem_log(data->client,
+ MODEM_LOG_ERROR,
+ "Unknown argument: '%s'\n",
+ argv[optind]);
+ print_help();
+ return EX_USAGE;
+ }
+
+ optind++;
+ }
+
+ if (data->command == CMD_NONE) {
+ ipc_modem_log(
+ data->client, MODEM_LOG_ERROR,
+ "\n"
+ "Error: No command given. You need to use a command.\n"
+ " See the help below for more details.\n"
+ "\n");
+ print_help();
+ return EX_USAGE;
+ }
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ struct ipc_modem_data data;
+ int ret;
+
+ bzero((void *)&data, sizeof(data));
+
+ data.client = ipc_client_create(IPC_CLIENT_TYPE_DUMMY);
+
+ ret = parse_cmdline_opts(&data, argc, argv);
+ if (ret)
+ return ret;
+
+ if (!data.dry_run) {
+ ipc_client_destroy(data.client);
+ data.client = ipc_client_create(IPC_CLIENT_TYPE_FMT);
+
+ if (data.client == 0) {
+ data.client = ipc_client_create(IPC_CLIENT_TYPE_DUMMY);
+ if (data.client)
+ ipc_modem_log(
+ data.client,
+ MODEM_LOG_ERROR,
+ "Could not create IPC client; "
+ "aborting ...\n");
+ else
+ printf("Could not create IPC client; "
+ "aborting ...\n");
+
+ return EX_UNAVAILABLE;
+ }
+ }
+
+ if (data.debug == 0)
+ ipc_client_log_callback_register(data.client,
+ modem_log_handler_quiet,
+ NULL);
+ else
+ ipc_client_log_callback_register(data.client,
+ modem_log_handler,
+ NULL);
+
+ print_cmdline_opts(&data);
+
+ return handle_command(&data);
+}
diff --git a/tools/ipc-modem/ipc-modem.h b/tools/ipc-modem/ipc-modem.h
new file mode 100644
index 0000000..0ba2f8e
--- /dev/null
+++ b/tools/ipc-modem/ipc-modem.h
@@ -0,0 +1,51 @@
+/*
+ * This file is part of libsamsung-ipc.
+ *
+ * Copyright (C) 2011 Simon Busch <morphis@gravedo.de>
+ * Copyright (C) 2011 Paul Kocialkowsk <contact@paulk.fr>
+ * Copyright (C) 2022 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
+ *
+ * libsamsung-ipc 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libsamsung-ipc 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 libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef IPC_MODEM_H
+#define IPC_MODEM_H
+
+#define MODEM_STATE_LPM 0
+#define MODEM_STATE_NORMAL 2
+#define MODEM_STATE_SIM_OK 4
+
+enum command {
+ CMD_NONE,
+ CMD_START,
+ CMD_BOOT,
+ CMD_POWER_ON,
+ CMD_POWER_OFF,
+};
+
+struct ipc_modem_data {
+ struct ipc_client *client;
+ char call_number[14];
+ char sim_pin[8];
+ enum command command;
+ bool debug;
+ bool dry_run;
+ /* State */
+ bool call_done;
+ bool in_call;
+ bool out_call;
+ int state;
+ int seq;
+};
+
+#endif /* IPC_MODEM */
diff --git a/tools/ipc-modem/tests/ipc-modem.py b/tools/ipc-modem/tests/ipc-modem.py
new file mode 100755
index 0000000..d04f40d
--- /dev/null
+++ b/tools/ipc-modem/tests/ipc-modem.py
@@ -0,0 +1,145 @@
+#!/usr/bin/env python3
+#
+# This file is part of libsamsung-ipc.
+#
+# Copyright (C) 2020 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
+#
+# libsamsung-ipc 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 2 of the License, or
+# (at your option) any later version.
+#
+# libsamsung-ipc 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 libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import re
+import sys
+import sh
+
+# sysexits.h
+class SysExit(object):
+ #define EX_USAGE 64 /* command line usage error */
+ EX_USAGE = sh.ErrorReturnCode_64
+
+def usage(progname):
+ print('{} [test]'.format(progname))
+ sys.exit(1)
+
+def get_output(data):
+ return str(data).replace(os.linesep, '')
+
+class IpcModem(object):
+ def __init__(self):
+ srcdir = os.environ.get('srcdir', None)
+
+ command_path = ''
+ if srcdir:
+ command_path = '.' + os.sep + 'ipc-modem'
+ # Enable to run tests without automake
+ else:
+ command_path = os.path.dirname(sys.argv[0]) \
+ + os.sep \
+ + '..' \
+ + os.sep \
+ + 'ipc-modem'
+
+ if 'VALGRIND' in os.environ:
+ self.timeout = 60
+ ipc_modem = sh.Command(os.environ['VALGRIND'])
+ self.ipc_modem = ipc_modem.bake('-v',
+ '--log-file=valgrind.%p.log',
+ '--leak-check=full',
+ command_path,
+ '--dry-run')
+ else:
+ self.timeout = 3
+ ipc_modem = sh.Command(command_path)
+ self.ipc_modem = ipc_modem.bake('--dry-run')
+
+ def test_help(self):
+ try:
+ self.ipc_modem()
+ except SysExit.EX_USAGE:
+ pass
+ else:
+ raise Exception()
+
+ def test_boot(self, timeout=None):
+ if timeout==None:
+ timeout = self.timeout
+
+ self.ipc_modem('boot', _timeout=timeout)
+
+ def test_power_on(self, timeout=None):
+ if timeout==None:
+ timeout = self.timeout
+
+ self.ipc_modem('power-on', _timeout=timeout)
+
+ def test_power_off(self, timeout=None):
+ if timeout==None:
+ timeout = self.timeout
+
+ self.ipc_modem('power-off', _timeout=timeout)
+
+ def test_start(self, timeout=None):
+ if timeout==None:
+ timeout = self.timeout
+
+ try:
+ self.ipc_modem('start', _timeout=timeout)
+ except sh.TimeoutException:
+ pass
+ else:
+ raise Exception()
+
+ def test_call_with_number(self, timeout=None):
+ if timeout==None:
+ timeout = self.timeout
+
+ expected_output = "[I] Got call number!"
+ output = ""
+ try:
+ output = get_output(self.ipc_modem('power-on',
+ '--call=0102030405',
+ _timeout=timeout))
+ except:
+ raise Exception()
+
+ if output != expected_output:
+ raise Exception()
+
+ def test_call_without_number(self, timeout=None):
+ if timeout==None:
+ timeout = self.timeout
+
+ expected_output = "[E] Missing call number"
+ output = get_output(self.ipc_modem('power-on',
+ '--call=',
+ _timeout=timeout,
+ _ok_code=SysExit.EX_USAGE.exit_code))
+ if output != expected_output:
+ raise Exception()
+
+ def test_commands(self):
+ self.test_boot()
+ self.test_power_on()
+ self.test_power_off()
+ self.test_start()
+ self.test_call_with_number()
+ self.test_call_without_number()
+
+def main():
+ ipc_modem = IpcModem()
+ ipc_modem.test_help()
+ ipc_modem.test_commands()
+
+if __name__ == '__main__':
+ rc = main()
+ sys.exit(rc)
diff --git a/tools/nv_data-imei.c b/tools/nv_data-imei.c
index 2c04079..aa62e0c 100644
--- a/tools/nv_data-imei.c
+++ b/tools/nv_data-imei.c
@@ -84,7 +84,7 @@ static int list_supported(void)
return 0;
}
-static int get_offset(struct command *command, void *arg)
+static int get_offset(const struct command *command, void *arg)
{
struct offset *offset = arg;
size_t i;
@@ -146,7 +146,7 @@ static int get_offset(struct command *command, void *arg)
return 0;
}
-static int get_imei(struct command *command, void *arg)
+static int get_imei(const struct command *command, void *arg)
{
struct imei *imei = arg;
@@ -180,7 +180,7 @@ static int get_imei(struct command *command, void *arg)
imei->optarg);
printf("In addition it is also invalid"
" as it is composed of "
- "%d digits instead of %d.\n",
+ "%zd digits instead of %d.\n",
len, IMEI_LENGTH);
return -EINVAL;
} else if (!str_is_digit) {
@@ -192,7 +192,7 @@ static int get_imei(struct command *command, void *arg)
} else if (!str_len_valid) {
printf("The '%s' "
"IMEI is invalid as it is composed of "
- "%d digits instead of %d.\n",
+ "%zd digits instead of %d.\n",
imei->optarg, len, IMEI_LENGTH);
return -EINVAL;
}
@@ -213,7 +213,7 @@ static int get_imei(struct command *command, void *arg)
return 0;
}
-static struct command_option commands_options[] = {
+static const struct command_option commands_options[] = {
{
OPTION_FILE,
"",
@@ -242,10 +242,10 @@ static struct command_option commands_options[] = {
"--imei=355921041234567",
get_imei,
},
- { /* Sentinel */ },
+ { 0 },
};
-static struct command commands[] = {
+static const struct command commands[] = {
{
"list-supported",
"Display supported devices and EFS",
@@ -274,7 +274,7 @@ static struct command commands[] = {
OPTION_FILE|OPTION_IMEI,
bruteforce_imei_offset,
},
- { /* Sentinel */ },
+ { 0 },
};
#if DEBUG
@@ -348,12 +348,12 @@ static void print_warnings(void)
}
/* TODO: Enforce type to only allow valid OPTION_* */
-static void *get_option(uint8_t given_option)
+static const struct command_option *get_option(uint8_t given_option)
{
int i = 0;
while (true) {
- struct command_option *command_option =
+ const struct command_option *command_option =
&(commands_options[i++]);
/* TODO: Get C to do something like if (!option) */
@@ -372,7 +372,7 @@ static int print_all_options(void)
int i = 0;
while (true) {
- struct command_option *option = &(commands_options[i++]);
+ const struct command_option *option = &(commands_options[i++]);
/* TODO: Get C to do something like if (!option) */
if (!option->option)
@@ -402,7 +402,7 @@ static int nv_data_imei_help(void)
printf("Commands:\n");
while (true) {
- struct command *cmd = &(commands[i++]);
+ const struct command *cmd = &(commands[i++]);
/* TODO: Get C to do something like if (!cmd) */
if (!cmd->name)
@@ -419,12 +419,12 @@ static int nv_data_imei_help(void)
return 0;
}
-static void *get_command(const char *name)
+static const struct command *get_command(const char *name)
{
int i = 0;
while (true) {
- struct command *cmd = &(commands[i++]);
+ const struct command *cmd = &(commands[i++]);
/* TODO: Get C to do something like if (!cmd) */
if (!cmd->name)
@@ -444,7 +444,7 @@ static void *get_command(const char *name)
static int command_help(const char *command_name)
{
- struct command *command;
+ const struct command *command;
size_t i;
command = get_command(command_name);
@@ -462,8 +462,8 @@ static int command_help(const char *command_name)
if (command->options & BIT(i)) {
bool required = !!(command->required_options &
BIT(i));
- struct command_option *option = get_option(
- command->options & BIT(i));
+ const struct command_option *option =
+ get_option(command->options & BIT(i));
/* Check if option and commands are in sync */
assert(option != NULL);
@@ -486,8 +486,8 @@ static int command_help(const char *command_name)
printf("Options:\n");
for (i = 0; i < (8 * sizeof(command->options)); i++) {
if (command->options & BIT(i)) {
- struct command_option *option = get_option(
- command->options & BIT(i));
+ const struct command_option *option =
+ get_option(command->options & BIT(i));
/* Check if option and commands are in sync */
assert(option != NULL);
@@ -510,8 +510,8 @@ static int command_help(const char *command_name)
if (command->options) {
for (i = 0; i < (8 * sizeof(command->options)); i++) {
if (command->required_options & BIT(i)) {
- struct command_option *option = get_option(
- command->options & BIT(i));
+ const struct command_option *option =
+ get_option(command->options & BIT(i));
/* Check if option and commands are in sync */
assert(option != NULL);
@@ -766,7 +766,11 @@ int write_imei(char *nv_data_path, struct offset *offset,
assert(imei->imei);
assert(strlen(imei->imei) == IMEI_LENGTH);
- asprintf(&md5_path, "%s.md5", nv_data_path);
+ rc = asprintf(&md5_path, "%s.md5", nv_data_path);
+ if (rc == -1) {
+ ipc_client_log(client, "%s: asprintf failed", __func__);
+ return -1;
+ }
/* We only support one device so far */
nv_data_secret = XMM616_NV_DATA_SECRET;
@@ -843,9 +847,9 @@ int main(int argc, char * const argv[])
opterr = 0;
struct imei imei;
struct offset offset;
- struct command *command = NULL;
- struct command_option *option = NULL;
- char *nv_data_path;
+ const struct command *command = NULL;
+ const struct command_option *option = NULL;
+ char *nv_data_path = NULL;
int c, rc;
memset(&imei, 0, sizeof(imei));
diff --git a/tools/nv_data-imei.h b/tools/nv_data-imei.h
index cb35808..7a153c2 100644
--- a/tools/nv_data-imei.h
+++ b/tools/nv_data-imei.h
@@ -66,7 +66,7 @@ struct command_option {
const char *option_string;
const char *help;
const char *example;
- int (*get_data)(struct command *command, void *arg);
+ int (*get_data)(const struct command *command, void *arg);
};
#define NO_OPTIONS 0
diff --git a/tools/nv_data-md5.c b/tools/nv_data-md5.c
index e8c9fc8..5edb257 100644
--- a/tools/nv_data-md5.c
+++ b/tools/nv_data-md5.c
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sysexits.h>
#include <sys/types.h>
@@ -100,4 +101,6 @@ int main(int argc, char *argv[])
error:
if (client != NULL)
ipc_client_destroy(client);
+
+ return EX_SOFTWARE;
}
diff --git a/tools/nv_data-imei.py b/tools/tests/nv_data-imei.py
index da58a50..3447690 100755
--- a/tools/nv_data-imei.py
+++ b/tools/tests/nv_data-imei.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# This file is part of libsamsung-ipc.
#
@@ -30,89 +30,110 @@ class SysExit(object):
EX_NOINPUT = sh.ErrorReturnCode_66
def usage(progname):
- print("{} [test]".format(progname))
+ print('{} [test]'.format(progname))
sys.exit(1)
commands = [
- "list-supported",
- "read-imei",
- "write-imei",
- "bruteforce-imei",
+ 'list-supported',
+ 'read-imei',
+ 'write-imei',
+ 'bruteforce-imei',
]
def get_output(data):
- return str(data).replace(os.linesep, "")
+ return str(data).replace(os.linesep, '')
class NvDataImei(object):
def __init__(self):
srcdir = os.environ.get('srcdir', None)
- # Enable also to test without automake
- if not srcdir:
- srcdir = os.path.dirname(sys.argv[0])
- self.nv_data_imei = sh.Command(srcdir + os.sep + "nv_data-imei")
+ command_path = ''
+ if srcdir:
+ command_path = '.' + os.sep + 'nv_data-imei'
+ # Enable to run tests without automake
+ else:
+ command_path = os.path.dirname(sys.argv[0]) \
+ + os.sep \
+ + '..' \
+ + os.sep \
+ + 'nv_data-imei'
+
+ if 'VALGRIND' in os.environ:
+ self.nv_data_imei = sh.Command(os.environ['VALGRIND'])
+ self.nv_data_imei = self.nv_data_imei.bake(
+ '-v',
+ '--log-file=valgrind.%p.log',
+ '--leak-check=full',
+ command_path)
+ else:
+ self.nv_data_imei = sh.Command(command_path)
+
def test_help(self):
try:
- self.nv_data_imei("")
+ self.nv_data_imei('')
except SysExit.EX_USAGE:
pass
else:
raise Exception()
- for help_arg in ["-h", "--help"]:
+ for help_arg in ['-h', '--help']:
self.nv_data_imei(help_arg)
for command in commands:
self.nv_data_imei(command, help_arg)
try:
- self.nv_data_imei("file", command, help_arg)
+ self.nv_data_imei('file', command, help_arg)
except SysExit.EX_USAGE:
pass
else:
raise Exception()
- self.nv_data_imei("list-supported")
+ self.nv_data_imei('list-supported')
def test_commands(self):
# Create nv_data.bin
- valid_imei = "123456789012345"
+ valid_imei = '123456789012345'
offset = 0x100
XMM616_NV_DATA_SIZE = 0x200000
nv_data_bin = get_output(sh.mktemp())
- sh.ddrescue("/dev/zero", nv_data_bin, "-s", str(XMM616_NV_DATA_SIZE))
+ sh.ddrescue('/dev/zero', nv_data_bin, '-s', str(XMM616_NV_DATA_SIZE))
- self.nv_data_imei(nv_data_bin, "write-imei", "-o", str(hex(offset)),
- "-i", valid_imei)
- output = get_output(self.nv_data_imei(nv_data_bin, "read-imei", "-o",
+ self.nv_data_imei(nv_data_bin, 'write-imei', '-o', str(hex(offset)),
+ '-i', valid_imei)
+ output = get_output(self.nv_data_imei(nv_data_bin, 'read-imei', '-o',
str(hex(offset))))
print(output)
- expect = "IMEI: " + valid_imei
+ expect = 'IMEI: ' + valid_imei
if output != expect:
raise Exception()
- output = get_output(self.nv_data_imei(nv_data_bin, "bruteforce-imei",
- "-i", valid_imei))
+ output = get_output(self.nv_data_imei(nv_data_bin, 'bruteforce-imei',
+ '-i', valid_imei))
print(output)
- expect = re.escape("Found IMEI at {} ({})".format(str(hex(offset)),
+ expect = re.escape('Found IMEI at {} ({})'.format(str(hex(offset)),
offset))
if not re.search(expect, output):
raise Exception()
- inaccessible_nv_data_bin = str(sh.mktemp("-u")).replace(os.linesep,"")
- sh.ddrescue("/dev/zero", inaccessible_nv_data_bin, "-s",
+ inaccessible_nv_data_bin = str(sh.mktemp('-u')).replace(os.linesep,'')
+ sh.ddrescue('/dev/zero', inaccessible_nv_data_bin, '-s',
str(XMM616_NV_DATA_SIZE))
- sh.chmod("000", inaccessible_nv_data_bin);
+ sh.chmod('000', inaccessible_nv_data_bin);
try:
- self.nv_data_imei(inaccessible_nv_data_bin, "write-imei",
- "-o", "0x0", "-i", valid_imei)
- self.nv_data_imei(inaccessible_nv_data_bin, "read-imei",
- "-o", "0x0")
- self.nv_data_imei(inaccessible_nv_data_bin, "bruteforce-imei",
- "-i", valid_imei)
+ self.nv_data_imei(inaccessible_nv_data_bin, 'write-imei',
+ '-o', '0x0', '-i', valid_imei)
+ self.nv_data_imei(inaccessible_nv_data_bin, 'read-imei',
+ '-o', '0x0')
+ self.nv_data_imei(inaccessible_nv_data_bin, 'bruteforce-imei',
+ '-i', valid_imei)
except SysExit.EX_NOINPUT:
pass
else:
raise Exception()
+ os.unlink(inaccessible_nv_data_bin)
+ os.unlink(nv_data_bin)
+ os.unlink(nv_data_bin + '.md5')
+
def main():
nv_data_imei = NvDataImei()
nv_data_imei.test_help()
diff --git a/tools/nv_data-md5.py b/tools/tests/nv_data-md5.py
index 2897f18..374ded2 100755
--- a/tools/nv_data-md5.py
+++ b/tools/tests/nv_data-md5.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# This file is part of libsamsung-ipc.
#
@@ -23,20 +23,36 @@ import sys
import sh
def usage(progname):
- print("{} [test]".format(progname))
+ print('{} [test]'.format(progname))
sys.exit(1)
def get_output(data):
- return str(data).replace(os.linesep, "")
+ return str(data).replace(os.linesep, '')
class NvDataMD5(object):
def __init__(self):
srcdir = os.environ.get('srcdir', None)
- # Enable also to test without automake
- if not srcdir:
- srcdir = os.path.dirname(sys.argv[0])
- self.nv_data_md5 = sh.Command(srcdir + os.sep + "nv_data-md5")
+ command_path = ''
+ if srcdir:
+ command_path = '.' + os.sep + 'nv_data-md5'
+ # Enable to run tests without automake
+ else:
+ command_path = os.path.dirname(sys.argv[0]) \
+ + os.sep \
+ + '..' \
+ + os.sep \
+ + 'nv_data-md5'
+
+ if 'VALGRIND' in os.environ:
+ self.nv_data_md5 = sh.Command(os.environ['VALGRIND'])
+ self.nv_data_md5 = self.nv_data_md5.bake(
+ '-v',
+ '--log-file=valgrind.%p.log',
+ '--leak-check=full',
+ command_path)
+ else:
+ self.nv_data_md5 = sh.Command(command_path)
def test_help(self):
try:
self.nv_data_md5()
@@ -46,12 +62,12 @@ class NvDataMD5(object):
raise Exception()
def test_commands(self):
- expected_md5 = "5293814414abb3831e3fc1a1b35e69bc"
+ expected_md5 = '5293814414abb3831e3fc1a1b35e69bc'
NV_DATA_SIZE = 0x200000
nv_data_bin = get_output(sh.mktemp())
# Create nv_data.bin
- sh.ddrescue("/dev/zero", nv_data_bin, "-s", str(NV_DATA_SIZE))
+ sh.ddrescue('/dev/zero', nv_data_bin, '-s', str(NV_DATA_SIZE))
output = get_output(self.nv_data_md5(nv_data_bin))
@@ -60,6 +76,8 @@ class NvDataMD5(object):
if output != expected_md5:
raise Exception()
+ os.unlink(nv_data_bin)
+
def main():
nv_data_md5 = NvDataMD5()
nv_data_md5.test_help()