INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include/)
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Werror -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wdeclaration-after-statement -Wmissing-declarations -Wredundant-decls -Wcast-align")
+SET(ADDITIONAL_CFLAGS "-Wall -Wno-array-bounds -Wno-empty-body -Wno-ignored-qualifiers -Wshadow -Wwrite-strings -Wswitch-default -Wno-unused-but-set-parameter -Wno-unused-but-set-variable -Wcast-qual")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror -Wextra -fvisibility=hidden -fPIC")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-parameter -Wno-missing-field-initializers -Wdeclaration-after-statement -Wmissing-declarations -Wredundant-decls -Wcast-align")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ADDITIONAL_CFLAGS}")
-ADD_DEFINITIONS("-DFEATURE_DLOG_DEBUG")
+ADD_DEFINITIONS("-DFEATURE_TLOG_DEBUG")
ADD_DEFINITIONS("-DTCORE_LOG_TAG=\"VMODEM\"")
+ADD_DEFINITIONS("-DPLUGIN_VERSION=${VERSION}")
+ADD_DEFINITIONS("-DEXPORT_API=__attribute__((visibility(\"default\")))")
MESSAGE(${CMAKE_C_FLAGS})
-MESSAGE(${CMAKE_EXE_LINKER_FLAGS})
+MESSAGE(${pkgs_LDFLAGS})
SET(SRCS
src/desc-vmodem.c
# install
INSTALL(TARGETS vmodem-plugin
LIBRARY DESTINATION lib/telephony/plugins)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION /usr/share/license RENAME tel-plugin-vmodem)
--- /dev/null
+AT based modem plugin
+++ /dev/null
-tel-plugin-vmodem (0.1.4) unstable; urgency=low
-
- * package version sync with public
- * Git: slp/pkgs/t/tel-plugin-vmodem
- * Tag: tel-plugin-vmodem_0.1.4
-
- -- Inho Oh <inho48.oh@samsung.com> Mon, 02 Apr 2012 16:10:33 +0900
-
-tel-plugin-vmodem (0.1.3) unstable; urgency=low
-
- * Fix prefix (TAPI_ to TCORE_)
- * Git: slp/pkgs/t/tel-plugin-vmodem
- * Tag: tel-plugin-vmodem_0.1.3
-
- -- Inho Oh <inho48.oh@samsung.com> Tue, 27 Mar 2012 22:11:38 +0900
-
-tel-plugin-vmodem (0.1.2) unstable; urgency=low
-
- * Fix build break and Add .spec file for OBS
- * Git: slp/pkgs/t/tel-plugin-vmodem
- * Tag: tel-plugin-vmodem_0.1.2
-
- -- DongHoo Park <donghoo.park@samsung.com> Sat, 17 Mar 2012 02:30:20 +0900
-
-tel-plugin-vmodem (0.1.1) unstable; urgency=low
-
- * Remove unused header
- * Git: slp/pkgs/t/tel-plugin-vmodem
- * Tag: tel-plugin-vmodem_0.1.1
-
- -- Inho Oh <inho48.oh@samsung.com> Fri, 16 Mar 2012 02:39:47 +0900
-
-tel-plugin-vmodem (0.1.0) unstable; urgency=low
-
- * Initial
- * Git: slp/pkgs/t/tel-plugin-vmodem
- * Tag: tel-plugin-vmodem_0.1.0
-
- -- Inho Oh <inho48.oh@samsung.com> Thu, 27 Mar 2012 20:50:00 +0900
+++ /dev/null
-Source: tel-plugin-vmodem
-Section: libs
-Priority: extra
-Maintainer: Jongman Park <jman.park@samsung.com>
-Uploaders: Jayoung Gu <jygu@samsung.com>, Kyeongchul Kim <kyeongchul.kim@samsung.com>, Youngman Park <youngman.park@samsung.com>, Inho Oh <inho48.oh@samsung.com>, DongHoo Park <donghoo.park@samsung.com>
-Build-Depends: debhelper (>= 5), libglib2.0-dev, libtcore-dev, dlog-dev
-Standards-Version: 0.0.0
-
-Package: tel-plugin-vmodem
-Section: libs
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends},
-Description: telephony client API library (Shared Object)
-
-Package: tel-plugin-vmodem-dbg
-Section: debug
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, tel-plugin-vmodem (= ${Source-Version})
-Description: telephony client API library (dbg package)
-
+++ /dev/null
-Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License version 2.1.
-
-The full text of the LGPL 2.1 can be found in
-/usr/share/common-licenses.
+++ /dev/null
-usr/bin
-usr/sbin
+++ /dev/null
-#!/usr/bin/make -f
-# -*- makefile -*-
-# Sample debian/rules that uses debhelper.
-# This file was originally written by Joey Hess and Craig Small.
-# As a special exception, when this file is copied by dh-make into a
-# dh-make output file, you may use that output file without restriction.
-# This special exception was added by Craig Small in version 0.37 of dh-make.
-
-# Uncomment this to turn on verbose mode.
-#export DH_VERBOSE=1
-
-CFLAGS ?= -Wall -g
-CXXFLAGS ?= -Wall -g
-LDFLAGS ?=
-PREFIX ?= /usr
-DATADIR ?= /opt
-
-ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
- CFLAGS += -O0
- CXXFLAGS += -O0
-else
- CFLAGS += -O2
- CXXFLAGS += -O2
-endif
-
-#CFLAGS += -fvisibility=hidden -fPIC
-CFLAGS += -fvisibility=default -fPIC
-LDFLAGS += -rdynamic -fPIC -Wl,--rpath=$(PREFIX)/lib -Wl,--as-needed
-#LDFLAGS += -Wl,--unresolved-symbols=ignore-in-shared-libs,--as-needed
-
-CMAKE_TMP_DIR = $(CURDIR)/cmake_tmp
-
-configure: configure-stamp
-configure-stamp:
- dh_testdir
- # Add here commands to configure the package.
- mkdir -p $(CMAKE_TMP_DIR);
- cd $(CMAKE_TMP_DIR); CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" cmake .. -DCMAKE_INSTALL_PREFIX=$(PREFIX)
-
- touch configure-stamp
-
-build: build-stamp
-
-build-stamp: configure-stamp
- dh_testdir
-
- # Add here commands to compile the package.
- cd $(CMAKE_TMP_DIR) && $(MAKE) all
-
- for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
- cat $$f > $${f%.in}; \
- sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \
- sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \
- done
-
- touch $@
-
-clean:
- dh_testdir
- dh_testroot
- rm -f build-stamp configure-stamp
-
- # Add here commands to clean up after the build process.
- rm -rf $(CMAKE_TMP_DIR)
-
- for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
- rm -f $${f%.in}; \
- done
-
- dh_clean
-
-install: build
- dh_testdir
- dh_testroot
- dh_clean -k
- dh_installdirs
-
- # Add here commands to install the package into debian/wavplayer.
- cd $(CMAKE_TMP_DIR) && $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
-
-
-# Build architecture-independent files here.
-binary-indep: build install
-# We have nothing to do by default.
-
-# Build architecture-dependent files here.
-binary-arch: build install
- dh_testdir
- dh_testroot
- dh_installchangelogs
- dh_installdocs
- dh_installexamples
- dh_install --sourcedir=debian/tmp
-# dh_installmenu
-# dh_installdebconf
-# dh_installlogrotate
-# dh_installemacsen
-# dh_installpam
-# dh_installmime
-# dh_python
-# dh_installinit
-# dh_installcron
-# dh_installinfo
- dh_installman
- dh_link
- dh_strip --dbg-package=tel-plugin-vmodem-dbg
- dh_compress
- dh_fixperms
-# dh_perl
- dh_makeshlibs
- dh_installdeb
- dh_shlibdeps --dpkg-shlibdeps-params="-v"
- dh_gencontrol
- dh_md5sums
- dh_builddeb
-
-binary: binary-indep binary-arch
-.PHONY: build clean binary-indep binary-arch binary install configure
+++ /dev/null
-@PREFIX@/lib/*
/*
- * libslp-tapi
+ * tel-plugin-vmodem
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved.
*
-/*\r
- * tel-plugin-vmodem\r
- *\r
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.\r
- *\r
- * Contact: Junhwan An <jh48.an@samsung.com>\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#ifndef __VDPRAM_H__\r
-#define __VDPRAM_H__\r
-\r
-int vdpram_close(int fd);\r
-int vdpram_open (void);\r
-int vdpramerr_open(void);\r
-int vdpram_poweron(int fd);\r
-int vdpram_poweroff(int fd);\r
-\r
-int vdpram_tty_read(int nFd, void* buf, size_t nbytes);\r
-int vdpram_tty_write(int nFd, void* buf, size_t nbytes);\r
-\r
-#endif\r
+/*
+ * tel-plugin-vmodem
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Junhwan An <jh48.an@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __VDPRAM_H__
+#define __VDPRAM_H__
+
+int vdpram_close(int fd);
+int vdpram_open (void);
+int vdpramerr_open(void);
+int vdpram_poweron(int fd);
+int vdpram_poweroff(int fd);
+
+int vdpram_tty_read(int nFd, void* buf, size_t nbytes);
+int vdpram_tty_write(int nFd, void* buf, size_t nbytes);
+
+#endif
-/*\r
- * tel-plugin-vmodem\r
- *\r
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.\r
- *\r
- * Contact: Junhwan An <jh48.an@samsung.com>\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#ifndef __VDPRAM_DUMP_H__\r
-#define __VDPRAM_DUMP_H__\r
-\r
-#define IPC_TX 0\r
-#define IPC_RX 1\r
-\r
-void vdpram_hex_dump(int dir, unsigned short data_len, void *data);\r
-\r
-#endif\r
-\r
+/*
+ * tel-plugin-vmodem
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Junhwan An <jh48.an@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __VDPRAM_DUMP_H__
+#define __VDPRAM_DUMP_H__
+
+#define IPC_TX 0
+#define IPC_RX 1
+
+void vdpram_hex_dump(int dir, unsigned short data_len, void *data);
+
+#endif
+
-#sbs-git:slp/pkgs/t/tel-plugin-vmodem
-Name: tel-plugin-vmodem
-Summary: Telephony AT Virtual Modem library
-Version: 0.1.6
-Release: 1
-Group: System/Libraries
-License: Apache
-Source0: tel-plugin-vmodem-%{version}.tar.gz
-Requires(post): /sbin/ldconfig
-Requires(postun): /sbin/ldconfig
+%define major 0
+%define minor 1
+%define patchlevel 20
+
+Name: tel-plugin-vmodem
+Version: %{major}.%{minor}.%{patchlevel}
+Release: 1
+License: Apache-2.0
+Summary: Telephony AT Virtual Modem library
+Group: System/Libraries
+Source0: tel-plugin-vmodem-%{version}.tar.gz
+
+%if "%{_repository}" == "emulator" || "%{_repository}" == "emulator-circle"
+%else
+ExcludeArch: %{arm} %ix86 x86_64
+%endif
+
BuildRequires: cmake
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(dlog)
BuildRequires: pkgconfig(tcore)
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
%description
Telephony AT Modem library
%setup -q
%build
-cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix}
-make %{?jobs:-j%jobs}
+versionint=$[%{major} * 1000000 + %{minor} * 1000 + %{patchlevel}]
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DVERSION=$versionint
+make %{?_smp_mflags}
%post
/sbin/ldconfig
%postun -p /sbin/ldconfig
%install
-rm -rf %{buildroot}
%make_install
+mkdir -p %{buildroot}/usr/share/license
%files
+%manifest tel-plugin-vmodem.manifest
%defattr(-,root,root,-)
#%doc COPYING
%{_libdir}/telephony/plugins/vmodem-plugin*
+/usr/share/license/tel-plugin-vmodem
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
+#include <fcntl.h>
#include <glib.h>
#include <tcore.h>
#include <plugin.h>
-
-#include <tcore.h>
#include <server.h>
-#include <plugin.h>
#include <user_request.h>
#include <hal.h>
+#include <core_object.h>
#include "vdpram.h"
+#define SERVER_INIT_WAIT_TIMEOUT 500
+
+#define DEVICE_NAME_LEN_MAX 16
+#define DEVICE_NAME_PREFIX "pdp"
+
+#define BUF_LEN_MAX 512
+
+#define CORE_OBJECT_NAME_MAX 16
+
+#define MODEM_PLUGIN_NAME "atmodem-plugin.so"
+
+#define BIT_SIZE(type) (sizeof(type) * 8)
+
+#define COPY_MASK(type) ((0xffffffff) >> (32 - BIT_SIZE(type)))
+
+#define MASK(width, offset, data) \
+ (((width) == BIT_SIZE(data)) ? (data) : \
+ ((((COPY_MASK(data) << (BIT_SIZE(data) - ((width) % BIT_SIZE(data)))) & COPY_MASK(data)) >> (offset)) & (data))) \
+
+
+#define MASK_AND_SHIFT(width, offset, shift, data) \
+ ((((signed) (shift)) < 0) ? \
+ MASK((width), (offset), (data)) << -(shift) : \
+ MASK((width), (offset), (data)) >> (((signed) (shift)))) \
+
struct custom_data {
int vdpram_fd;
guint watch_id_vdpram;
};
-static TReturn hal_power(TcoreHal *hal, gboolean flag)
+typedef struct {
+ TcoreHal *hal;
+ TcoreModem *modem;
+} PluginData;
+
+struct v_modules {
+ unsigned int co_type;
+ char co_name[CORE_OBJECT_NAME_MAX];
+};
+
+static char __util_unpackb(const char *src, int pos, int len)
+{
+ char result = 0;
+ int rshift = 0;
+
+ src += pos / 8;
+ pos %= 8;
+
+ rshift = MAX(8 - (pos + len), 0);
+
+ if (rshift > 0) {
+ result = MASK_AND_SHIFT(len, pos, rshift, (unsigned char)*src);
+ } else {
+ result = MASK(8 - pos, pos, (unsigned char)*src);
+ src++;
+ len -= 8 - pos;
+
+ if (len > 0) result = (result << len) | (*src >> (8 - len)); // if any bits left
+ }
+
+ return result;
+}
+
+static char __util_convert_byte_hexchar(char val)
+{
+ char hex_char;
+
+ if (val <= 9) {
+ hex_char = (char) (val + '0');
+ } else if (val >= 10 && val <= 15) {
+ hex_char = (char) (val - 10 + 'A');
+ } else {
+ hex_char = '0';
+ }
+
+ return (hex_char);
+}
+
+static gboolean __util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes)
+{
+ int i;
+ char nibble;
+ int buf_pos = 0;
+
+ for (i = 0; i < num_bytes * 2; i++) {
+ nibble = __util_unpackb(byte_pdu, buf_pos, 4);
+ buf_pos += 4;
+ hex_pdu[i] = __util_convert_byte_hexchar(nibble);
+ }
+
+ return TRUE;
+}
+
+static TcoreModem *__get_modem(TcorePlugin *modem_iface_plugin)
+{
+ PluginData *user_data;
+
+ if (modem_iface_plugin == NULL)
+ return NULL;
+
+ user_data = tcore_plugin_ref_user_data(modem_iface_plugin);
+ if (user_data == NULL)
+ return NULL;
+
+ /* 'modem' corresponding to Modem Interface plug-in */
+ return user_data->modem;
+}
+
+static guint __vmodem_reencode_mt_sms(gchar *mt_sms, guint mt_sms_len)
+{
+#define VMODEM_CR 0x0D
+#define VMODEM_LF 0x0A
+#define VMODEM_COLON 0x3A
+
+ gchar sms_buf[BUF_LEN_MAX] = {0, };
+ guint sca_len, pdu_len, tpdu_len;
+ gushort tpdu_len_ptr = 0;
+ gchar tpdu_len_str[8] = {0};
+ guint i, local_index = 0;
+
+ if (mt_sms_len > (BUF_LEN_MAX - 2))
+ mt_sms_len = BUF_LEN_MAX - 2;
+
+ for (i = 0; i < mt_sms_len; i++) {
+ if ((mt_sms[i] == VMODEM_CR)
+ && (mt_sms[i+1] == VMODEM_LF)) {
+ sms_buf[i] = mt_sms[i];
+ i++;
+ sms_buf[i] = mt_sms[i];
+ i++;
+ break;
+ }
+ else if (mt_sms[i] == VMODEM_COLON)
+ tpdu_len_ptr = i+1;
+
+ /* Byte copy */
+ sms_buf[i] = mt_sms[i];
+ }
+ sca_len = mt_sms[i];
+ dbg("SCA length: [%d] TPDU length offset: [%d]", sca_len, tpdu_len_ptr);
+
+ pdu_len = (mt_sms_len-i);
+ tpdu_len = pdu_len - (sca_len+1);
+ dbg("PDU length: [%d] Actual TPDU Length: [%d]", pdu_len, tpdu_len);
+
+ if (pdu_len >= 100 && tpdu_len < 100) {
+ /*
+ * Move back complete buffer by a Byte (to fill up the
+ * void created by hundreds place).
+ */
+ if (i > 3) {
+ sms_buf[i-3] = VMODEM_CR;
+ sms_buf[i-2] = VMODEM_LF;
+
+ __util_byte_to_hex(&mt_sms[i], &sms_buf[i-1], pdu_len);
+ i += (2*pdu_len - 1);
+ }
+ } else {
+ __util_byte_to_hex(&mt_sms[i], &sms_buf[i], pdu_len);
+ i += 2*pdu_len;
+ }
+
+ /* Update actual TPDU length */
+ snprintf(tpdu_len_str, 8, "%d", tpdu_len);
+ switch (strlen(tpdu_len_str)) {
+ case 4: /* 100s place */
+ dbg("1000s : [%d]", tpdu_len_str[local_index]);
+
+ sms_buf[tpdu_len_ptr] = tpdu_len_str[local_index];
+ tpdu_len_ptr++;
+
+ local_index++;
+ case 3: /* 100s place */
+ dbg("100s : [%d]", tpdu_len_str[local_index]);
+
+ sms_buf[tpdu_len_ptr] = tpdu_len_str[local_index];
+ tpdu_len_ptr++;
+
+ local_index++;
+ case 2: /* 10s place */
+ dbg("10s : [%d]", tpdu_len_str[local_index]);
+
+ sms_buf[tpdu_len_ptr] = tpdu_len_str[local_index];
+ tpdu_len_ptr++;
+
+ local_index++;
+ case 1: /* 1s place */
+ dbg("1s : [%d]", tpdu_len_str[local_index]);
+
+ sms_buf[tpdu_len_ptr] = tpdu_len_str[local_index];
+ tpdu_len_ptr++;
+ break;
+ default:
+ dbg("Unsupported length: [%d]", strlen(tpdu_len_str));
+ break;
+ }
+
+ /*
+ * Greater than (BUF_LEN_MAX - 2),
+ * restrict the length to ( BUF_LEN_MAX - 2).
+ *
+ * This is to accomadate <CR> & <LF>.
+ */
+ if (i > (BUF_LEN_MAX - 2))
+ i = BUF_LEN_MAX - 2;
+
+ /* Append <CR> & <LF> */
+ sms_buf[i++] = VMODEM_CR;
+ sms_buf[i++] = VMODEM_LF;
+ dbg("MT SMS: [%s]", sms_buf);
+
+ tcore_util_hex_dump(" ", (int)i, sms_buf);
+
+ /*
+ * Copy back
+ *
+ * 'data_len' is not accessed hence it need not be updated.
+ */
+ g_strlcpy(mt_sms, sms_buf, i+1);
+ dbg("Encoded MT SMS: [%d][%s]", i, mt_sms);
+
+ return i;
+}
+
+static guint __register_gio_watch(TcoreHal *h, int fd, void *callback)
+{
+ GIOChannel *channel = NULL;
+ guint source;
+
+ dbg("Register to Watch list - fd: [%d]", fd);
+
+ if ((fd < 0) || (callback == NULL))
+ return 0;
+
+ channel = g_io_channel_unix_new(fd);
+ source = g_io_add_watch(channel, G_IO_IN, (GIOFunc) callback, h);
+ g_io_channel_unref(channel);
+ channel = NULL;
+
+ return source;
+}
+
+static void __deregister_gio_watch(guint watch_id)
+{
+ dbg("Deregister Watch ID: [%d]", watch_id);
+
+ /* Remove source */
+ g_source_remove(watch_id);
+}
+
+static gboolean __load_modem_plugin(gpointer data)
{
+ TcoreHal *hal;
+ TcorePlugin *plugin;
struct custom_data *user_data;
+ TcoreModem *modem;
+ unsigned int slot_count = 1;
+
+ dbg("Entry");
+
+ if (data == NULL) {
+ err("data is NULL");
+ return FALSE;
+ }
+
+ hal = data;
+ plugin = tcore_hal_ref_plugin(hal);
+ modem = __get_modem(plugin);
+ /* Load Modem Plug-in */
+ if (tcore_server_load_modem_plugin(tcore_plugin_ref_server(plugin),
+ modem, MODEM_PLUGIN_NAME) == TCORE_RETURN_FAILURE) {
+ err("Load Modem Plug-in - [FAIL]");
+
+ goto EXIT;
+ } else {
+ dbg("Load Modem Plug-in - [SUCCESS]");
+ }
+
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ NULL, TNOTI_SERVER_ADDED_MODEM_PLUGIN_COMPLETED,
+ sizeof(slot_count), &slot_count);
+
+ /* To stop the cycle need to return FALSE */
+ return FALSE;
+
+EXIT:
user_data = tcore_hal_ref_user_data(hal);
- if (!user_data)
+ if (user_data == NULL)
+ return FALSE;
+
+ /* Deregister from Watch list */
+ __deregister_gio_watch(user_data->watch_id_vdpram);
+
+ /* Free HAL */
+ tcore_hal_free(hal);
+
+ /* Close VDPRAM device */
+ vdpram_close(user_data->vdpram_fd);
+
+ /* Free custom data */
+ g_free(user_data);
+
+ return FALSE;
+}
+
+static TReturn _modem_power(TcoreHal *hal, gboolean enable)
+{
+ struct custom_data *user_data;
+
+ user_data = tcore_hal_ref_user_data(hal);
+ if (user_data == NULL) {
+ err(" User data is NULL");
return TCORE_RETURN_FAILURE;
+ }
- /* power on */
- if (flag == TRUE) {
+ if (enable == TRUE) { /* POWER ON */
if (FALSE == vdpram_poweron(user_data->vdpram_fd)) {
- err("vdpram_poweron failed");
+ err(" Power ON - [FAIL]");
return TCORE_RETURN_FAILURE;
}
+
+ /* Set Power State - ON */
tcore_hal_set_power_state(hal, TRUE);
- }
- /* power off */
- else {
- if (FALSE == vdpram_poweroff(user_data->vdpram_fd)) {
- err("vdpram_poweroff failed");
+ } else { /* POWER OFF */
+ if (vdpram_poweroff(user_data->vdpram_fd) == FALSE) {
+ err(" Power OFF - [FAIL]");
return TCORE_RETURN_FAILURE;
}
+
+ /* Set Power state - OFF */
tcore_hal_set_power_state(hal, FALSE);
}
return TCORE_RETURN_SUCCESS;
}
+static gboolean on_recv_vdpram_message(GIOChannel *channel,
+ GIOCondition condition, gpointer data)
+{
+ TcoreHal *hal = data;
+ struct custom_data *custom;
+ char buf[BUF_LEN_MAX];
+ int n = 0;
+ TReturn ret;
+
+ custom = tcore_hal_ref_user_data(hal);
+ memset(buf, 0x0, BUF_LEN_MAX);
+
+ /* Read from Device */
+ n = vdpram_tty_read(custom->vdpram_fd, buf, BUF_LEN_MAX);
+ if (n < 0) {
+ err(" Read error - Data received: [%d]", n);
+ return TRUE;
+ }
+ dbg(" DPRAM Receive - Data length: [%d]", n);
+
+ msg("\n---------- [RECV] Length of received data: [%d] ----------\n", n);
+
+ /* Emit receive callback */
+ tcore_hal_emit_recv_callback(hal, n, buf);
+
+ /*
+ * This is to ensure that the received MT SMS (+CMT:) is
+ * encoded according to 3GPP standard
+ */
+ if (buf[0] == 0x2B && buf[1] == 0x43 && buf[2] == 0x4D
+ && buf[3] == 0x54 && buf[4] == 0x3A) {
+ dbg("Received - [MT SMS]");
+ n = __vmodem_reencode_mt_sms((gchar *)buf, n);
+ }
+ else if (buf[0] == 0x25) {
+ dbg("Replaced % --> +");
+ buf[0] = 0x2B;
+ }
+
+ /* Dispatch received data to response handler */
+ dbg("Invoking tcore_hal_dispatch_response_data()");
+ ret = tcore_hal_dispatch_response_data(hal, 0, n, buf);
+ msg("\n---------- [RECV FINISH] Receive processing: [%d] ----------\n", ret);
+
+ return TRUE;
+}
+
+static TReturn hal_power(TcoreHal *hal, gboolean flag)
+{
+ return _modem_power(hal, flag);
+}
static TReturn hal_send(TcoreHal *hal, unsigned int data_len, void *data)
{
int ret;
struct custom_data *user_data;
- if (tcore_hal_get_power_state(hal) == FALSE)
+ if (tcore_hal_get_power_state(hal) == FALSE) {
+ err(" HAL Power state - OFF");
return TCORE_RETURN_FAILURE;
+ }
user_data = tcore_hal_ref_user_data(hal);
- if (!user_data)
+ if (user_data == NULL) {
+ err(" User data is NULL");
return TCORE_RETURN_FAILURE;
+ }
ret = vdpram_tty_write(user_data->vdpram_fd, data, data_len);
if(ret < 0) {
- err("vdpram_tty_write failed");
+ err(" Write failed");
return TCORE_RETURN_FAILURE;
}
else {
- dbg("vdpram_tty_write success ret=%d (fd=%d, len=%d)", ret, user_data->vdpram_fd, data_len);
+ dbg("vdpram_tty_write success ret=%d (fd=%d, len=%d)",
+ ret, user_data->vdpram_fd, data_len);
return TCORE_RETURN_SUCCESS;
}
}
-
-static struct tcore_hal_operations hops =
+static TReturn hal_setup_netif(CoreObject *co,
+ TcoreHalSetupNetifCallback func, void *user_data,
+ unsigned int cid, gboolean enable)
{
- .power = hal_power,
- .send = hal_send,
-};
+ char ifname[DEVICE_NAME_LEN_MAX];
+ int size = 0;
+ int fd = 0;
+ char buf[32];
+ const char *control = NULL;
+
+ if (cid > 3) {
+ err(" Context ID: [%d]", cid);
+ return TCORE_RETURN_EINVAL;
+ }
-static gboolean on_recv_vdpram_message(GIOChannel *channel, GIOCondition condition, gpointer data)
-{
- TcoreHal *hal = data;
- struct custom_data *custom;
+ if (enable == TRUE) {
+ dbg(" ACTIVATE - Context ID: [%d]", cid);
+ control = "/sys/class/net/svnet0/pdp/activate";
+ } else {
+ dbg(" DEACTIVATE - Context ID: [%d]", cid);
+ control = "/sys/class/net/svnet0/pdp/deactivate";
+ }
- #define BUF_LEN_MAX 512
- char buf[BUF_LEN_MAX];
- int n = 0;
+ fd = open(control, O_WRONLY);
+ if (fd < 0) {
+ err(" Failed to Open interface: [%s]", control);
- custom = tcore_hal_ref_user_data(hal);
- memset(buf, 0, BUF_LEN_MAX);
- n = vdpram_tty_read(custom->vdpram_fd, buf, BUF_LEN_MAX);
- if (n < 0) {
- err("tty_read error. return_valute = %d", n);
- return TRUE;
- }
+ /* Invoke callback function */
+ if (func)
+ func(co, -1, NULL, user_data);
- dbg("vdpram recv (ret = %d)", n);
- tcore_hal_emit_recv_callback(hal, n, buf);
+ return TCORE_RETURN_FAILURE;
+ }
- return TRUE;
-}
+ /* Context ID needs to be written to the Device */
+ snprintf(buf, sizeof(buf), "%d", cid);
+ size = write(fd, buf, strlen(buf));
+ dbg(" SIZE [%d]", size);
-static guint register_gio_watch(TcoreHal *h, int fd, void *callback)
-{
- GIOChannel *channel = NULL;
- guint source;
+ /* Close 'fd' */
+ close(fd);
- if (fd < 0 || !callback)
- return 0;
+ /* Device name */
+ snprintf(ifname, DEVICE_NAME_LEN_MAX, "%s%d", DEVICE_NAME_PREFIX, (cid - 1));
+ dbg(" Interface Name: [%s]", ifname);
- channel = g_io_channel_unix_new(fd);
- source = g_io_add_watch(channel, G_IO_IN, (GIOFunc) callback, h);
- g_io_channel_unref(channel);
- channel = NULL;
+ /* Invoke callback function */
+ if (func)
+ func(co, 0, ifname, user_data);
- return source;
+ return TCORE_RETURN_SUCCESS;
}
-
-/*static int power_tx_pwr_on_exec(int nFd)
-{
- Not implement yet
- return 0;
-}*/
+/* HAL Operations */
+static struct tcore_hal_operations hal_ops = {
+ .power = hal_power,
+ .send = hal_send,
+ .setup_netif = hal_setup_netif,
+};
static gboolean on_load()
{
- dbg("i'm load!");
+ dbg(" Load!!!");
return TRUE;
}
static gboolean on_init(TcorePlugin *plugin)
{
TcoreHal *hal;
+ PluginData *user_data;
struct custom_data *data;
- if (!plugin)
+ dbg(" Init!!!");
+
+ if (plugin == NULL) {
+ err(" PLug-in is NULL");
return FALSE;
+ }
- dbg("i'm init!");
+ /* User Data for Modem Interface Plug-in */
+ user_data = g_try_new0(PluginData, 1);
+ if (user_data == NULL) {
+ err(" Failed to allocate memory for Plugin data");
+ return FALSE;
+ }
+
+ /* Register to Server */
+ user_data->modem = tcore_server_register_modem(tcore_plugin_ref_server(plugin), plugin);
+ if (user_data->modem == NULL){
+ err(" Registration Failed");
+ g_free(user_data);
+ return FALSE;
+ }
+ dbg(" Registered from Server");
+
+
+ data = g_try_new0(struct custom_data, 1);
+ if (data == NULL) {
+ err(" Failed to allocate memory for Custom data");
+
+ /* Unregister from Server */
+ tcore_server_unregister_modem(tcore_plugin_ref_server(plugin), user_data->modem);
+
+ /* Free Plugin data */
+ g_free(user_data);
+
+ return FALSE;
+ }
/*
- * Phonet init
+ * Open DPRAM device
*/
- data = calloc(sizeof(struct custom_data), 1);
- memset(data, 0, sizeof(struct custom_data));
-
data->vdpram_fd = vdpram_open();
+ if (data->vdpram_fd < 0) {
+ /* Fre custom data */
+ g_free(data);
+
+ /* Unregister from Server */
+ tcore_server_unregister_modem(tcore_plugin_ref_server(plugin), user_data->modem);
+
+ /* Free Plugin data */
+ g_free(user_data);
+ return FALSE;
+ }
/*
- * HAL init
+ * Create and initialize HAL
*/
- hal = tcore_hal_new(plugin, "vmodem", &hops, TCORE_HAL_MODE_CUSTOM);
- tcore_hal_link_user_data(hal, data);
+ hal = tcore_hal_new(plugin, "vmodem", &hal_ops, TCORE_HAL_MODE_AT);
+ if (hal == NULL) {
+ /* Close VDPRAM device */
+ vdpram_close(data->vdpram_fd);
- data->watch_id_vdpram= register_gio_watch(hal, data->vdpram_fd, on_recv_vdpram_message);
+ /* Fre custom data */
+ g_free(data);
- dbg("vdpram_fd = %d, watch_id_vdpram=%d ", data->vdpram_fd, data->watch_id_vdpram);
+ /* Unregister from Server */
+ tcore_server_unregister_modem(tcore_plugin_ref_server(plugin), user_data->modem);
- if (!vdpram_poweron(data->vdpram_fd))
- err("vdpram_poweron Failed");
+ /* Fre Plugin data */
+ g_free(user_data);
-// power_tx_pwr_on_exec(data->vdpram_fd);
+ return FALSE;
+ }
+ user_data->hal = hal;
+
+ /* Link custom data to HAL user data */
+ tcore_hal_link_user_data(hal, data);
+ /* Set HAL as Modem Interface Plug-in's User data */
+ tcore_plugin_link_user_data(plugin, user_data);
+
+ /* Register to Watch list */
+ data->watch_id_vdpram = __register_gio_watch(hal,
+ data->vdpram_fd, on_recv_vdpram_message);
+ dbg(" fd: [%d] Watch ID: [%d]",
+ data->vdpram_fd, data->watch_id_vdpram);
+
+ /* Power ON VDPRAM device */
+ if (_modem_power(hal, TRUE) == TCORE_RETURN_SUCCESS) {
+ dbg(" Power ON - [SUCCESS]");
+ } else {
+ err(" Power ON - [FAIL]");
+ goto EXIT;
+ }
+
+ /* Check CP Power ON */
+ g_timeout_add_full(G_PRIORITY_HIGH, SERVER_INIT_WAIT_TIMEOUT, __load_modem_plugin, hal, 0);
+
+ dbg("[VMMODEM] Exit");
return TRUE;
+
+EXIT:
+ /* Deregister from Watch list */
+ __deregister_gio_watch(data->watch_id_vdpram);
+
+ /* Free HAL */
+ tcore_hal_free(hal);
+
+ /* Close VDPRAM device */
+ vdpram_close(data->vdpram_fd);
+
+ /* Free custom data */
+ g_free(data);
+
+ /* Unregister from Server */
+ tcore_server_unregister_modem(tcore_plugin_ref_server(plugin), user_data->modem);
+
+ /*Free Plugin Data*/
+ g_free(user_data);
+
+ return FALSE;
}
static void on_unload(TcorePlugin *plugin)
{
- if (!plugin)
+ TcoreHal *hal;
+ struct custom_data *data;
+ PluginData *user_data;
+
+ dbg(" Unload!!!");
+
+ if (plugin == NULL)
+ return;
+
+ user_data = tcore_plugin_ref_user_data(plugin);
+ if (user_data == NULL)
+ return;
+
+ hal = user_data->hal;
+
+ /* Unload Modem Plug-in */
+#if 0 /* TODO - Open the code below */
+ tcore_server_unload_modem_plugin(tcore_plugin_ref_server(plugin), plugin);
+#endif
+ data = tcore_hal_ref_user_data(hal);
+ if (data == NULL)
return;
- dbg("i'm unload");
+ /* Deregister from Watch list */
+ __deregister_gio_watch(data->watch_id_vdpram);
+ dbg(" Deregistered Watch ID");
+
+ /* Free HAL */
+ tcore_hal_free(hal);
+ dbg(" Freed HAL");
+
+ /* Close VDPRAM device */
+ vdpram_close(data->vdpram_fd);
+ dbg(" Closed VDPRAM device");
+
+ /* Free custom data */
+ g_free(data);
+
+ tcore_server_unregister_modem(tcore_plugin_ref_server(plugin), user_data->modem);
+ dbg(" Unregistered from Server");
+
+ dbg(" Unloaded MODEM");
+ g_free(user_data);
}
-struct tcore_plugin_define_desc plugin_define_desc =
-{
+/* VMODEM Descriptor Structure */
+EXPORT_API struct tcore_plugin_define_desc plugin_define_desc = {
.name = "VMODEM",
.priority = TCORE_PLUGIN_PRIORITY_HIGH,
.version = 1,
-/*\r
- * tel-plugin-vmodem\r
- *\r
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.\r
- *\r
- * Contact: Junhwan An <jh48.an@samsung.com>\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <string.h>\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <termios.h>\r
-#include <errno.h>\r
-#include <sys/time.h>\r
-#include <sys/mman.h>\r
-#include <unistd.h>\r
-#include <fcntl.h>\r
-#include <sys/ioctl.h>\r
-\r
-#include <log.h>\r
-#include "legacy/TelUtility.h"\r
-#include "vdpram.h"\r
-#include "vdpram_dump.h"\r
-\r
-#ifndef TIOCMODG\r
-# ifdef TIOCMGET\r
-# define TIOCMODG TIOCMGET\r
-# else\r
-# ifdef MCGETA\r
-# define TIOCMODG MCGETA\r
-# endif\r
-# endif\r
-#endif\r
-\r
-#ifndef TIOCMODS\r
-# ifdef TIOCMSET\r
-# define TIOCMODS TIOCMSET\r
-# else\r
-# ifdef MCSETA\r
-# define TIOCMODS MCSETA\r
-# endif\r
-# endif\r
-#endif\r
-\r
-typedef struct _tty_old_setting_t{\r
- int fd;\r
- struct termios termiosVal;\r
- struct _tty_old_setting_t *next;\r
- struct _tty_old_setting_t *prev;\r
-} tty_old_setting_t;\r
-\r
-#define VDPRAM_OPEN_PATH "/dev/dpram/0"\r
-\r
-/* DPRAM ioctls for DPRAM tty devices */\r
-#define IOC_MZ_MAGIC ('h')\r
-#define HN_DPRAM_PHONE_ON _IO (IOC_MZ_MAGIC, 0xd0)\r
-#define HN_DPRAM_PHONE_OFF _IO (IOC_MZ_MAGIC, 0xd1)\r
-#define HN_DPRAM_PHONE_GETSTATUS _IOR(IOC_MZ_MAGIC, 0xd2, unsigned int)\r
-\r
-static tty_old_setting_t *ttyold_head = NULL;\r
-\r
-/* static functions */\r
-static void __insert_tty_oldsetting(tty_old_setting_t *me)\r
-{\r
- dbg("Function Enterence.");\r
-\r
- if (me == NULL)\r
- return;\r
-\r
- if (ttyold_head)\r
- ttyold_head->prev = me;\r
-\r
- me->next = ttyold_head;\r
- me->prev = 0;\r
- ttyold_head = me;\r
-}\r
-\r
-static tty_old_setting_t *__search_tty_oldsetting(int fd)\r
-{\r
- tty_old_setting_t *tty = NULL;\r
-\r
- dbg("Function Enterence.");\r
-\r
- if (ttyold_head == NULL)\r
- return NULL;\r
-\r
- tty = ttyold_head;\r
-\r
- do{\r
- if (tty->fd == fd) {\r
- dbg("oldsetting for inputted fd is found");\r
- break;\r
- }\r
- else {\r
- if (tty->next == NULL) {\r
- dbg("No oldsetting is found");\r
- tty = NULL;\r
- break;\r
- }\r
- tty = tty->next;\r
- }\r
- }while(1);\r
-\r
- return tty;\r
-}\r
-\r
-static void __remove_tty_oldsetting(tty_old_setting_t *me)\r
-{\r
- dbg( "Function Enterence.");\r
-\r
- if (me == NULL)\r
- return;\r
-\r
- if (me->prev)\r
- me->prev->next = me->next;\r
- else\r
- ttyold_head = me->next;\r
-\r
- if (me->next)\r
- me->next->prev = me->prev;\r
-}\r
-\r
-/* Set hardware flow control.\r
-*/\r
-static void __tty_sethwf(int fd, int on)\r
-{\r
- struct termios tty;\r
-\r
- dbg("Function Enterence.");\r
-\r
- if (tcgetattr(fd, &tty))\r
- err("__tty_sethwf: tcgetattr:");\r
-\r
- if (on)\r
- tty.c_cflag |= CRTSCTS;\r
- else\r
- tty.c_cflag &= ~CRTSCTS;\r
-\r
- if (tcsetattr(fd, TCSANOW, &tty))\r
- err("__tty_sethwf: tcsetattr:");\r
-}\r
-\r
-/*\r
-* Set RTS line. Sometimes dropped. Linux specific?\r
-*/\r
-static int __tty_setrts(int fd)\r
-{\r
- int mcs;\r
-\r
- dbg("Function Enterence.");\r
-\r
- if (-1 == ioctl(fd, TIOCMODG, &mcs))\r
- err("icotl: TIOCMODG");\r
-\r
- mcs |= TIOCM_RTS;\r
-\r
- if (-1 == ioctl(fd, TIOCMODS, &mcs))\r
- err("icotl: TIOCMODS");\r
-\r
- return 0;\r
-}\r
-\r
-/*\r
- * Set baudrate, parity and number of bits.\r
- */\r
-static int __tty_setparms(int fd, char* baudr, char* par, char* bits, char* stop, int hwf, int swf)\r
-{\r
- int spd = -1;\r
- int newbaud;\r
- int bit = bits[0];\r
- int stop_bit = stop[0];\r
-\r
- struct termios tty;\r
- tty_old_setting_t *old_setting = NULL;\r
-\r
- dbg("Function Enterence.");\r
-\r
- old_setting = calloc(sizeof(tty_old_setting_t), 1);\r
-\r
- if (old_setting == NULL)\r
- return TAPI_API_SYSTEM_OUT_OF_MEM;\r
-\r
- old_setting->fd = fd;\r
-\r
- if (tcgetattr(fd, &tty) < 0) {\r
- free(old_setting);\r
- return TAPI_API_TRANSPORT_LAYER_FAILURE;\r
- }\r
-\r
- if (tcgetattr(fd, &old_setting->termiosVal) < 0) {\r
- free(old_setting);\r
- return TAPI_API_TRANSPORT_LAYER_FAILURE;\r
- }\r
-\r
- __insert_tty_oldsetting(old_setting);\r
-\r
- fflush(stdout);\r
-\r
- /* We generate mark and space parity ourself. */\r
- if (bit == '7' && (par[0] == 'M' || par[0] == 'S'))\r
- bit = '8';\r
-\r
- /* Check if 'baudr' is really a number */\r
- if ((newbaud = (atol(baudr) / 100)) == 0 && baudr[0] != '0')\r
- newbaud = -1;\r
-\r
- switch(newbaud)\r
- {\r
- case 0:\r
- spd = 0;\r
- break;\r
-\r
- case 3:\r
- spd = B300;\r
- break;\r
-\r
- case 6:\r
- spd = B600;\r
- break;\r
-\r
- case 12:\r
- spd = B1200;\r
- break;\r
-\r
- case 24:\r
- spd = B2400;\r
- break;\r
-\r
- case 48:\r
- spd = B4800;\r
- break;\r
-\r
- case 96:\r
- spd = B9600;\r
- break;\r
-\r
- case 192:\r
- spd = B19200;\r
- break;\r
-\r
- case 384:\r
- spd = B38400;\r
- break;\r
-\r
- case 576:\r
- spd = B57600;\r
- break;\r
-\r
- case 1152:\r
- spd = B115200;\r
- break;\r
-\r
- default:\r
- err("invaid baud rate");\r
- break;\r
- }\r
-\r
- if (spd != -1) {\r
- cfsetospeed(&tty, (speed_t) spd);\r
- cfsetispeed(&tty, (speed_t) spd);\r
- }\r
-\r
- switch(bit)\r
- {\r
- case '5':\r
- tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS5;\r
- break;\r
-\r
- case '6':\r
- tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS6;\r
- break;\r
-\r
- case '7':\r
- tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS7;\r
- break;\r
-\r
- case '8':\r
- default:\r
- tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;\r
- break;\r
- }\r
-\r
- switch(stop_bit)\r
- {\r
- case '1':\r
- tty.c_cflag &= ~CSTOPB;\r
- break;\r
-\r
- case '2':\r
- default:\r
- tty.c_cflag |= CSTOPB;\r
- break;\r
- }\r
-\r
- /* Set into raw, no echo mode */\r
- tty.c_iflag = IGNBRK;\r
- tty.c_lflag = 0;\r
- tty.c_oflag = 0;\r
- tty.c_cflag |= CLOCAL | CREAD;\r
- tty.c_cc[VMIN] = 1;\r
- tty.c_cc[VTIME] = 1;\r
-\r
- if (swf)\r
- tty.c_iflag |= IXON | IXOFF;\r
- else\r
- tty.c_iflag &= ~(IXON | IXOFF | IXANY);\r
-\r
- tty.c_cflag &= ~(PARENB | PARODD);\r
-\r
- if (par[0] == 'E')\r
- tty.c_cflag |= PARENB;\r
- else if (par[0] == 'O')\r
- tty.c_cflag |= (PARENB | PARODD);\r
-\r
- if (tcsetattr(fd, TCSANOW, &tty) < 0) {\r
- free(old_setting);\r
- return TAPI_API_TRANSPORT_LAYER_FAILURE;\r
- }\r
-\r
- __tty_setrts(fd);\r
- __tty_sethwf(fd, hwf);\r
-\r
- return TAPI_API_SUCCESS;\r
-\r
-}\r
-\r
-static int __tty_close(int fd)\r
-{\r
- tty_old_setting_t *old_setting = NULL;\r
-\r
- dbg("Function Enterence.");\r
-\r
- old_setting = __search_tty_oldsetting(fd);\r
- if (old_setting == NULL)\r
- return TAPI_API_SUCCESS;\r
-\r
- if (tcsetattr(fd, TCSAFLUSH, &old_setting->termiosVal) < 0) {\r
- err("close failed");\r
- return TAPI_API_TRANSPORT_LAYER_FAILURE;\r
- }\r
-\r
- __remove_tty_oldsetting(old_setting);\r
-\r
- free(old_setting);\r
-\r
- close(fd);\r
-\r
- return TAPI_API_SUCCESS;\r
-}\r
-\r
-/*\r
-* restore the old settings before close.\r
-*/\r
-int vdpram_close(int fd)\r
-{\r
- int ret = TAPI_API_SUCCESS;\r
-\r
- dbg("Function Enterence.");\r
-\r
- ret = __tty_close(fd);\r
-\r
- return ret;\r
-}\r
-\r
-/*\r
-* Open the vdpram fd.\r
-*/\r
-int vdpram_open (void)\r
-{\r
- int rv = -1;\r
- int fd = -1;\r
- int val = 0;\r
- unsigned int cmd =0;\r
-\r
- fd = open(VDPRAM_OPEN_PATH, O_RDWR);\r
-\r
- if (fd < 0) {\r
- err("#### Failed to open vdpram file: error no hex %x", errno);\r
- return rv;\r
- }\r
- else\r
- dbg("#### Success to open vdpram file. fd:%d, path:%s", fd, VDPRAM_OPEN_PATH);\r
-\r
-\r
- if (__tty_setparms(fd, "115200", "N", "8", "1", 0, 0) != TAPI_API_SUCCESS) {\r
- vdpram_close(fd);\r
- return rv;\r
- }\r
- else\r
- dbg("#### Success set tty vdpram params. fd:%d", fd);\r
-\r
- /*TODO: No need to check Status. Delete*/\r
- cmd = HN_DPRAM_PHONE_GETSTATUS;\r
-\r
- if (ioctl(fd, cmd, &val) < 0) {\r
- err("#### ioctl failed fd:%d, cmd:%lu, val:%d", fd,cmd,val);\r
- vdpram_close(fd);\r
- return rv;\r
- }\r
- else\r
- dbg("#### ioctl Success fd:%d, cmd:%lu, val:%d", fd,cmd,val);\r
-\r
- return fd;\r
-\r
-}\r
-\r
-/*\r
-* power on the phone.\r
-*/\r
-int vdpram_poweron(int fd)\r
-{\r
- int rv = -1;\r
-\r
- if (ioctl(fd, HN_DPRAM_PHONE_ON, NULL) < 0) {\r
- err("Phone Power On failed (fd:%d)", fd);\r
- rv = 0;\r
- }\r
- else {\r
- dbg("Phone Power On success (fd:%d)", fd);\r
- rv = 1;\r
- }\r
- return rv;\r
-}\r
-\r
- /*\r
- * Power Off the Phone.\r
- */\r
-int vdpram_poweroff(int fd)\r
-{\r
- int rv;\r
-\r
- if (ioctl(fd, HN_DPRAM_PHONE_OFF, NULL) < 0) {\r
- err("Phone Power Off failed.");\r
- rv = -1;\r
- }\r
- else {\r
- dbg("Phone Power Off success.");\r
- rv = 1;\r
- }\r
-\r
- return rv;\r
-}\r
-\r
-/*\r
-* Read data from vdpram.\r
-*/\r
-\r
-int vdpram_tty_read(int nFd, void* buf, size_t nbytes)\r
-{\r
- int actual = 0;\r
-\r
- if ((actual = read(nFd, buf, nbytes)) < 0) {\r
- dbg("[TRANSPORT DPRAM]read failed.");\r
- }\r
- vdpram_hex_dump(IPC_RX, actual, buf);\r
-\r
- return actual;\r
-}\r
-\r
-static void __selectsleep(int sec,int msec)\r
-{\r
- struct timeval tv;\r
- tv.tv_sec=sec;\r
- tv.tv_usec=msec;\r
- select(0,NULL,NULL,NULL,&tv);\r
- return;\r
-}\r
-\r
-/*\r
-* Write data to vdpram.\r
-*/\r
-int vdpram_tty_write(int nFd, void* buf, size_t nbytes)\r
-{\r
- int ret;\r
- size_t actual = 0;\r
- int retry = 0;\r
-\r
- do {\r
- vdpram_hex_dump(IPC_TX, nbytes, buf);\r
- ret = write(nFd, (unsigned char* )buf, nbytes - actual);\r
-\r
- if ((ret < 0 && errno == EAGAIN) || (ret < 0 && errno == EBUSY)) {\r
- err("write failed. retry.. ret[%d] with errno[%d] ",ret, errno);\r
- __selectsleep(0,50);\r
-\r
- if (retry == 10)\r
- return 0;\r
-\r
- retry = retry + 1;\r
- continue;\r
- }\r
-\r
- if (ret < 0) {\r
- if (actual != nbytes)\r
- err("write failed.ret[%d]",ret);\r
-\r
- err("errno [%d]",errno);\r
- return actual;\r
- }\r
-\r
- actual += ret;\r
- buf += ret;\r
-\r
- } while(actual < nbytes);\r
-\r
- return actual;\r
-}\r
-/* EOF */\r
+/*
+ * tel-plugin-vmodem
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Junhwan An <jh48.an@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <termios.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#include <log.h>
+#include "legacy/TelUtility.h"
+#include "vdpram.h"
+#include "vdpram_dump.h"
+
+#ifndef TIOCMODG
+# ifdef TIOCMGET
+# define TIOCMODG TIOCMGET
+# else
+# ifdef MCGETA
+# define TIOCMODG MCGETA
+# endif
+# endif
+#endif
+
+#ifndef TIOCMODS
+# ifdef TIOCMSET
+# define TIOCMODS TIOCMSET
+# else
+# ifdef MCSETA
+# define TIOCMODS MCSETA
+# endif
+# endif
+#endif
+
+typedef struct _tty_old_setting_t{
+ int fd;
+ struct termios termiosVal;
+ struct _tty_old_setting_t *next;
+ struct _tty_old_setting_t *prev;
+} tty_old_setting_t;
+
+#define VDPRAM_OPEN_PATH "/dev/vdpram0"
+
+/* DPRAM ioctls for DPRAM tty devices */
+#define IOC_MZ_MAGIC ('h')
+#define HN_DPRAM_PHONE_ON _IO (IOC_MZ_MAGIC, 0xd0)
+#define HN_DPRAM_PHONE_OFF _IO (IOC_MZ_MAGIC, 0xd1)
+#define HN_DPRAM_PHONE_GETSTATUS _IOR(IOC_MZ_MAGIC, 0xd2, unsigned int)
+
+static tty_old_setting_t *ttyold_head = NULL;
+
+/* static functions */
+static void __insert_tty_oldsetting(tty_old_setting_t *me)
+{
+ dbg("Function Enterence.");
+
+ if (me == NULL)
+ return;
+
+ if (ttyold_head)
+ ttyold_head->prev = me;
+
+ me->next = ttyold_head;
+ me->prev = 0;
+ ttyold_head = me;
+}
+
+static tty_old_setting_t *__search_tty_oldsetting(int fd)
+{
+ tty_old_setting_t *tty = NULL;
+
+ dbg("Function Enterence.");
+
+ if (ttyold_head == NULL)
+ return NULL;
+
+ tty = ttyold_head;
+
+ do{
+ if (tty->fd == fd) {
+ dbg("oldsetting for inputted fd is found");
+ break;
+ }
+ else {
+ if (tty->next == NULL) {
+ dbg("No oldsetting is found");
+ tty = NULL;
+ break;
+ }
+ tty = tty->next;
+ }
+ }while(1);
+
+ return tty;
+}
+
+static void __remove_tty_oldsetting(tty_old_setting_t *me)
+{
+ dbg( "Function Enterence.");
+
+ if (me == NULL)
+ return;
+
+ if (me->prev)
+ me->prev->next = me->next;
+ else
+ ttyold_head = me->next;
+
+ if (me->next)
+ me->next->prev = me->prev;
+}
+
+/* Set hardware flow control.
+*/
+static void __tty_sethwf(int fd, int on)
+{
+ struct termios tty;
+
+ dbg("Function Enterence.");
+
+ if (tcgetattr(fd, &tty))
+ err("__tty_sethwf: tcgetattr:");
+
+ if (on)
+ tty.c_cflag |= CRTSCTS;
+ else
+ tty.c_cflag &= ~CRTSCTS;
+
+ if (tcsetattr(fd, TCSANOW, &tty))
+ err("__tty_sethwf: tcsetattr:");
+}
+
+/*
+* Set RTS line. Sometimes dropped. Linux specific?
+*/
+static int __tty_setrts(int fd)
+{
+ int mcs;
+
+ dbg("Function Enterence.");
+
+ if (-1 == ioctl(fd, TIOCMODG, &mcs))
+ err("icotl: TIOCMODG");
+
+ mcs |= TIOCM_RTS;
+
+ if (-1 == ioctl(fd, TIOCMODS, &mcs))
+ err("icotl: TIOCMODS");
+
+ return 0;
+}
+
+/*
+ * Set baudrate, parity and number of bits.
+ */
+static int __tty_setparms(int fd,
+ const char* baudr, const char* par,
+ const char* bits, const char* stop,
+ int hwf, int swf)
+{
+ int spd = -1;
+ int newbaud;
+ int bit = bits[0];
+ int stop_bit = stop[0];
+
+ struct termios tty;
+ tty_old_setting_t *old_setting = NULL;
+
+ dbg("Function Enterence.");
+
+ old_setting = calloc(sizeof(tty_old_setting_t), 1);
+
+ if (old_setting == NULL)
+ return TAPI_API_SYSTEM_OUT_OF_MEM;
+
+ old_setting->fd = fd;
+
+ if (tcgetattr(fd, &tty) < 0) {
+ free(old_setting);
+ return TAPI_API_TRANSPORT_LAYER_FAILURE;
+ }
+
+ if (tcgetattr(fd, &old_setting->termiosVal) < 0) {
+ free(old_setting);
+ return TAPI_API_TRANSPORT_LAYER_FAILURE;
+ }
+
+ __insert_tty_oldsetting(old_setting);
+
+ fflush(stdout);
+
+ /* We generate mark and space parity ourself. */
+ if (bit == '7' && (par[0] == 'M' || par[0] == 'S'))
+ bit = '8';
+
+ /* Check if 'baudr' is really a number */
+ if ((newbaud = (atol(baudr) / 100)) == 0 && baudr[0] != '0')
+ newbaud = -1;
+
+ switch(newbaud)
+ {
+ case 0:
+ spd = 0;
+ break;
+
+ case 3:
+ spd = B300;
+ break;
+
+ case 6:
+ spd = B600;
+ break;
+
+ case 12:
+ spd = B1200;
+ break;
+
+ case 24:
+ spd = B2400;
+ break;
+
+ case 48:
+ spd = B4800;
+ break;
+
+ case 96:
+ spd = B9600;
+ break;
+
+ case 192:
+ spd = B19200;
+ break;
+
+ case 384:
+ spd = B38400;
+ break;
+
+ case 576:
+ spd = B57600;
+ break;
+
+ case 1152:
+ spd = B115200;
+ break;
+
+ default:
+ err("invaid baud rate");
+ break;
+ }
+
+ if (spd != -1) {
+ cfsetospeed(&tty, (speed_t) spd);
+ cfsetispeed(&tty, (speed_t) spd);
+ }
+
+ switch(bit)
+ {
+ case '5':
+ tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS5;
+ break;
+
+ case '6':
+ tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS6;
+ break;
+
+ case '7':
+ tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS7;
+ break;
+
+ case '8':
+ default:
+ tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
+ break;
+ }
+
+ switch(stop_bit)
+ {
+ case '1':
+ tty.c_cflag &= ~CSTOPB;
+ break;
+
+ case '2':
+ default:
+ tty.c_cflag |= CSTOPB;
+ break;
+ }
+
+ /* Set into raw, no echo mode */
+ tty.c_iflag = IGNBRK;
+ tty.c_lflag = 0;
+ tty.c_oflag = 0;
+ tty.c_cflag |= CLOCAL | CREAD;
+ tty.c_cc[VMIN] = 1;
+ tty.c_cc[VTIME] = 1;
+
+ if (swf)
+ tty.c_iflag |= IXON | IXOFF;
+ else
+ tty.c_iflag &= ~(IXON | IXOFF | IXANY);
+
+ tty.c_cflag &= ~(PARENB | PARODD);
+
+ if (par[0] == 'E')
+ tty.c_cflag |= PARENB;
+ else if (par[0] == 'O')
+ tty.c_cflag |= (PARENB | PARODD);
+
+ if (tcsetattr(fd, TCSANOW, &tty) < 0) {
+ free(old_setting);
+ return TAPI_API_TRANSPORT_LAYER_FAILURE;
+ }
+
+ __tty_setrts(fd);
+ __tty_sethwf(fd, hwf);
+
+ return TAPI_API_SUCCESS;
+
+}
+
+static int __tty_close(int fd)
+{
+ tty_old_setting_t *old_setting = NULL;
+
+ dbg("Function Enterence.");
+
+ old_setting = __search_tty_oldsetting(fd);
+ if (old_setting == NULL)
+ return TAPI_API_SUCCESS;
+
+ if (tcsetattr(fd, TCSAFLUSH, &old_setting->termiosVal) < 0) {
+ err("close failed");
+ return TAPI_API_TRANSPORT_LAYER_FAILURE;
+ }
+
+ __remove_tty_oldsetting(old_setting);
+
+ free(old_setting);
+
+ close(fd);
+
+ return TAPI_API_SUCCESS;
+}
+
+/*
+* restore the old settings before close.
+*/
+int vdpram_close(int fd)
+{
+ int ret = TAPI_API_SUCCESS;
+
+ dbg("Function Enterence.");
+
+ ret = __tty_close(fd);
+
+ return ret;
+}
+
+/*
+* Open the vdpram fd.
+*/
+int vdpram_open (void)
+{
+ int rv = -1;
+ int fd = -1;
+ int val = 0;
+ unsigned int cmd =0;
+
+ fd = open(VDPRAM_OPEN_PATH, O_RDWR);
+
+ if (fd < 0) {
+ err("#### Failed to open vdpram file: error no hex %x", errno);
+ return rv;
+ }
+ else
+ dbg("#### Success to open vdpram file. fd:%d, path:%s", fd, VDPRAM_OPEN_PATH);
+
+
+ if (__tty_setparms(fd, "115200", "N", "8", "1", 0, 0) != TAPI_API_SUCCESS) {
+ vdpram_close(fd);
+ return rv;
+ }
+ else
+ dbg("#### Success set tty vdpram params. fd:%d", fd);
+
+ /*TODO: No need to check Status. Delete*/
+ cmd = HN_DPRAM_PHONE_GETSTATUS;
+
+ if (ioctl(fd, cmd, &val) < 0) {
+ err("#### ioctl failed fd:%d, cmd:%lu, val:%d", fd,cmd,val);
+ vdpram_close(fd);
+ return rv;
+ }
+ else
+ dbg("#### ioctl Success fd:%d, cmd:%lu, val:%d", fd,cmd,val);
+
+ return fd;
+
+}
+
+/*
+* power on the phone.
+*/
+int vdpram_poweron(int fd)
+{
+ int rv = -1;
+
+ if (ioctl(fd, HN_DPRAM_PHONE_ON, NULL) < 0) {
+ err("Phone Power On failed (fd:%d)", fd);
+ rv = 0;
+ }
+ else {
+ dbg("Phone Power On success (fd:%d)", fd);
+ rv = 1;
+ }
+ return rv;
+}
+
+ /*
+ * Power Off the Phone.
+ */
+int vdpram_poweroff(int fd)
+{
+ int rv;
+
+ if (ioctl(fd, HN_DPRAM_PHONE_OFF, NULL) < 0) {
+ err("Phone Power Off failed.");
+ rv = -1;
+ }
+ else {
+ dbg("Phone Power Off success.");
+ rv = 1;
+ }
+
+ return rv;
+}
+
+/*
+* Read data from vdpram.
+*/
+
+int vdpram_tty_read(int nFd, void* buf, size_t nbytes)
+{
+ int actual = 0;
+
+ if ((actual = read(nFd, buf, nbytes)) < 0) {
+ dbg("[TRANSPORT DPRAM]read failed.");
+ }
+ vdpram_hex_dump(IPC_RX, actual, buf);
+
+ return actual;
+}
+
+static void __selectsleep(int sec,int msec)
+{
+ struct timeval tv;
+ tv.tv_sec=sec;
+ tv.tv_usec=msec;
+ select(0,NULL,NULL,NULL,&tv);
+ return;
+}
+
+/*
+* Write data to vdpram.
+*/
+int vdpram_tty_write(int nFd, void* buf, size_t nbytes)
+{
+ int ret;
+ size_t actual = 0;
+ int retry = 0;
+
+ do {
+ vdpram_hex_dump(IPC_TX, nbytes, buf);
+ ret = write(nFd, (unsigned char* )buf, nbytes - actual);
+
+ if ((ret < 0 && errno == EAGAIN) || (ret < 0 && errno == EBUSY)) {
+ err("write failed. retry.. ret[%d] with errno[%d] ",ret, errno);
+ __selectsleep(0,50);
+
+ if (retry == 10)
+ return 0;
+
+ retry = retry + 1;
+ continue;
+ }
+
+ if (ret < 0) {
+ if (actual != nbytes)
+ err("write failed.ret[%d]",ret);
+
+ err("errno [%d]",errno);
+ return actual;
+ }
+
+ actual += ret;
+ buf += ret;
+
+ } while(actual < nbytes);
+
+ return actual;
+}
+/* EOF */
-/*\r
- * tel-plugin-vmodem\r
- *\r
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.\r
- *\r
- * Contact: Junhwan An <jh48.an@samsung.com>\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <string.h>\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <log.h>\r
-\r
-#include "vdpram_dump.h"\r
-\r
-static void hex_dump(char *pad, int size, const void *data)\r
-{\r
- char buf[255] = {0, };\r
- char hex[4] = {0, };\r
- int i;\r
- unsigned char *p;\r
-\r
- if (size <= 0) {\r
- msg("%sno data", pad);\r
- return;\r
- }\r
-\r
- p = (unsigned char *)data;\r
-\r
- snprintf(buf, 255, "%s%04X: ", pad, 0);\r
- for (i = 0; i<size; i++) {\r
- snprintf(hex, 4, "%02X ", p[i]);\r
- strcat(buf, hex);\r
-\r
- if ((i + 1) % 8 == 0) {\r
- if ((i + 1) % 16 == 0) {\r
- msg("%s", buf);\r
- memset(buf, 0, 255);\r
- snprintf(buf, 255, "%s%04X: ", pad, i + 1);\r
- }\r
- else {\r
- strcat(buf, " ");\r
- }\r
- }\r
- }\r
-\r
- msg("%s", buf);\r
-}\r
-\r
-void vdpram_hex_dump(int dir, unsigned short data_len, void *data)\r
-{\r
- char *d;\r
-\r
- if(!data)\r
- return;\r
-\r
- if (dir == IPC_RX)\r
- d = "[RX]";\r
- else\r
- d = "[TX]";\r
-\r
- msg("");\r
- msg(" %s\tlen=%d\t%s", d, data_len, (char *)data);\r
- hex_dump(" ", data_len, data);\r
-\r
- msg("");\r
-}\r
-\r
+/*
+ * tel-plugin-vmodem
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Junhwan An <jh48.an@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <log.h>
+
+#include "vdpram_dump.h"
+
+#define TAB_SPACE " "
+
+static void hex_dump(const char *pad, int size, const void *data)
+{
+ char buf[255] = {0, };
+ char hex[4] = {0, };
+ int i;
+ unsigned const char *p;
+
+ if (size <= 0) {
+ msg("%sno data", pad);
+ return;
+ }
+
+ p = (unsigned const char *)data;
+
+ snprintf(buf, 255, "%s%04X: ", pad, 0);
+ for (i = 0; i<size; i++) {
+ snprintf(hex, 4, "%02X ", p[i]);
+ strncat(buf, hex, strlen(hex));
+
+ if ((i + 1) % 8 == 0) {
+ if ((i + 1) % 16 == 0) {
+ msg("%s", buf);
+ memset(buf, 0, 255);
+ snprintf(buf, 255, "%s%04X: ", pad, i + 1);
+ }
+ else {
+ strncat(buf, TAB_SPACE, strlen(TAB_SPACE));
+ }
+ }
+ }
+
+ msg("%s", buf);
+}
+
+void vdpram_hex_dump(int dir, unsigned short data_len, void *data)
+{
+ const char *d;
+
+ if(!data)
+ return;
+
+ if (dir == IPC_RX)
+ d = "[RX]";
+ else
+ d = "[TX]";
+
+ msg("");
+ msg(" %s\tlen=%d\t%s", d, data_len, (char *)data);
+ hex_dump(" ", data_len, (const void*)data);
+
+ msg("");
+}
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>