From d13f113721f94b8aeb69a381b2a24ffa34cbf3da Mon Sep 17 00:00:00 2001
From: Walter Doekes <walter+github@wjd.nu>
Date: Sat, 5 Sep 2015 16:58:20 +0200
Subject: [PATCH 01/15] Parse a +CMGS notification and hack it to send an event
 with reference.

Author: me, some time in the past.
Source: /~dexter/work/asterisk-chan-dongle/patch.patch.txt
---
 at_command.c  |  2 +-
 at_parse.c    | 21 +++++++++++++++++++++
 at_parse.h    |  1 +
 at_response.c | 26 +++++++++++++++++++++++---
 pdu.c         | 27 ++++++++++++++++++++++++++-
 5 files changed, 72 insertions(+), 5 deletions(-)

diff --git a/at_command.c b/at_command.c
index c2515ee..8c2a5a7 100644
--- a/at_command.c
+++ b/at_command.c
@@ -133,7 +133,7 @@ EXPORT_DEF int at_enque_initialization(struct cpvt* cpvt, at_cmd_t from_command)
 	static const char cmd19[] = "AT+CSSN=1,1\r";
 	static const char cmd21[] = "AT+CSCS=\"UCS2\"\r";
 
-	static const char cmd22[] = "AT+CPMS=\"ME\",\"ME\",\"ME\"\r";
+	static const char cmd22[] = "AT+CPMS=\"SM\",\"SM\",\"SM\"\r";
 	static const char cmd23[] = "AT+CNMI=2,1,0,0,0\r";
 	static const char cmd24[] = "AT+CSQ\r";
 
diff --git a/at_parse.c b/at_parse.c
index e407e7f..27ef6d7 100644
--- a/at_parse.c
+++ b/at_parse.c
@@ -385,6 +385,27 @@ EXPORT_DEF const char * at_parse_cmgr(char ** str, size_t len, char * oa, size_t
 	return rv;
 }
 
+/*!
+ * \brief Parse a +CMGS notification
+ * \param str -- string to parse (null terminated)
+ * \return -1 on error (parse error) or the first integer value found
+ * \todo FIXME: parse <mr>[,<scts>] value correctly
+ */
+
+EXPORT_DEF int at_parse_cmgs (const char* str)
+{
+	int cmgs = -1;
+
+	/*
+	 * parse CMGS info in the following format:
+	 * +CMGS:<mr>[,<scts>]
+	 * (sscanf is lax about extra spaces)
+	 * TODO: not ignore parse errors ;)
+	 */
+	sscanf (str, "+CMGS:%d", &cmgs);
+	return cmgs;
+}
+
  /*!
  * \brief Parse a CUSD answer
  * \param str -- string to parse (null terminated)
diff --git a/at_parse.h b/at_parse.h
index 29a28b8..b2e2ed5 100644
--- a/at_parse.h
+++ b/at_parse.h
@@ -15,6 +15,7 @@ EXPORT_DECL char* at_parse_cops (char* str);
 EXPORT_DECL int at_parse_creg (char* str, unsigned len, int* gsm_reg, int* gsm_reg_status, char** lac, char** ci);
 EXPORT_DECL int at_parse_cmti (const char* str);
 EXPORT_DECL const char* at_parse_cmgr (char** str, size_t len, char* oa, size_t oa_len, str_encoding_t* oa_enc, char** msg, str_encoding_t* msg_enc);
+EXPORT_DECL int at_parse_cmgs (const char* str);
 EXPORT_DECL int at_parse_cusd (char* str, int * type, char ** cusd, int * dcs);
 EXPORT_DECL int at_parse_cpin (char* str, size_t len);
 EXPORT_DECL int at_parse_csq (const char* str, int* rssi);
diff --git a/at_response.c b/at_response.c
index 15c5531..e66be46 100644
--- a/at_response.c
+++ b/at_response.c
@@ -1198,8 +1198,16 @@ static int at_response_cmgr (struct pvt* pvt, const char * str, size_t len)
 		pvt_try_restate(pvt);
 
 		cmgr = err_pos = ast_strdupa (str);
-		err = at_parse_cmgr (&err_pos, len, oa, sizeof(oa), &oa_enc, &msg, &msg_enc);
-		if (err)
+		err = at_parse_cmgr (&err_pos, len, oa, sizeof(oa), &oa_enc, &msg, &msg_enc); // YYY
+		if (err == (void*)0x1) /* HACK! */
+		{
+			char buf[64];
+			int res = (int)(long)msg; /* HACK */
+			snprintf(buf, 64, "Delivered\r\nForeignID: %d", res);
+			manager_event_sent_notify(PVT_ID(pvt), "SMS", 0x0 /* task is popped */, buf);
+			return 0;
+		}
+		else if (err)
 		{
 			ast_log (LOG_WARNING, "[%s] Error parsing incoming message '%s' at possition %d: %s\n", PVT_ID(pvt), str, (int)(err_pos - cmgr), err);
 			return 0;
@@ -1722,11 +1730,23 @@ int at_response (struct pvt* pvt, const struct iovec iov[2], int iovcnt, at_res_
 			case RES_CSSU:
 			case RES_SRVST:
 			case RES_CVOICE:
-			case RES_CMGS:
 			case RES_CPMS:
 			case RES_CONF:
 				return 0;
 
+			case RES_CMGS:
+				/* Abuse the fact that we know how the manager
+				 * message are formatted: CRLF separated headers
+				 * with colon between key and value */
+				{
+					char buf[64];
+					int res = at_parse_cmgs(str);
+					const at_queue_task_t * task = at_queue_head_task (pvt);
+					snprintf(buf, 64, "Sending\r\nForeignID: %d", res);
+					manager_event_sent_notify(PVT_ID(pvt), "SMS", task, buf);
+				}
+				return 0;
+
 			case RES_OK:
 				at_response_ok (pvt, at_res);
 				return 0;
diff --git a/pdu.c b/pdu.c
index e3dae5b..5f87db3 100644
--- a/pdu.c
+++ b/pdu.c
@@ -797,10 +797,35 @@ EXPORT_DEF const char * pdu_parse(char ** pdu, size_t tpdu_length, char * oa, si
 					err = "Can't parse length of OA";
 				}
 			}
+			else if(PDUTYPE_MTI(pdu_type) == PDUTYPE_MTI_SMS_STATUS_REPORT)
+			{
+				int reference = pdu_parse_byte(pdu, &pdu_length);
+				/* Skip over 8 bytes TP-DA */
+				if (reference >= 0 && pdu_length >= 8) {
+					(*pdu) += 8;
+					pdu_length -= 8;
+					/* Skip over 7 bytes timestamp TP-SCTS */
+					if (pdu_parse_timestamp(pdu, &pdu_length) >= 0 &&
+					    /* Skip over 7 bytes timestamp TP-DT */
+					    pdu_parse_timestamp(pdu, &pdu_length) >= 0) {
+						int tp_status = pdu_parse_byte(pdu, &pdu_length);
+						if ((tp_status & 0xf) == 0) {
+							err = (void*)0x1; /* HACK! */
+							*msg = (char*)(ssize_t)reference; /* HACK! */
+						} else {
+							err = "Good report, but delivery failed";
+						}
+					} else {
+						err = "FIXME error 1";
+					}
+				} else {
+					err = "FIXME error 2";
+				}
+			}
 			else
 			{
 				*pdu -= 2;
-				err = "Unhandled PDU Type MTI only SMS-DELIVER supported";
+				err = "Unhandled PDU Type MTI only SMS-DELIVER/SMS-STATUS-REPORT supported";
 			}
 		}
 		else

From ea62b24513ddcbc5cf7184131d6dc438b96b66a7 Mon Sep 17 00:00:00 2001
From: Walter Doekes <walter+github@wjd.nu>
Date: Sat, 5 Sep 2015 16:59:39 +0200
Subject: [PATCH 02/15] Add Asterisk 10 support.

Author: me, some time in the past.
Source: /~dexter/work/asterisk-chan-dongle/patch2.patch.txt
---
 channel.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/channel.c b/channel.c
index 0c96fa4..cfd926a 100644
--- a/channel.c
+++ b/channel.c
@@ -95,18 +95,23 @@ EXPORT_DEF int channels_loop(struct pvt * pvt, const struct ast_channel * reques
 	return 0;
 }
 
-#if ASTERISK_VERSION_NUM >= 10800
+#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+
+static struct ast_channel * channel_request (attribute_unused const char * type, struct ast_format_cap * cap, const struct ast_channel *requestor, void * data, int * cause)
+
+#elif ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
 //   TODO: simplify by move common code to functions
 static struct ast_channel * channel_request (attribute_unused const char * type, format_t format, const struct ast_channel * requestor, void * data, int * cause)
 
-#else /* #if ASTERISK_VERSION_NUM >= 10800 */
+#else /* ASTERISK_VERSION_NUM < 10800 */
 /* TODO: add check when request 'holdother' what requestor is not on same device for 1.6 */
 
 static struct ast_channel * channel_request (attribute_unused const char * type, int format, void * data, int * cause)
 
-#endif /* #if ASTERISK_VERSION_NUM >= 10800 */
+#endif /* ASTERISK_VERSION_NUM */
 {
-#if ASTERISK_VERSION_NUM >= 10800
+#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+#elif ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
 	format_t oldformat;
 #else
 	int oldformat;
@@ -126,11 +131,18 @@ static struct ast_channel * channel_request (attribute_unused const char * type,
 		return NULL;
 	}
 
+#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+	if (!(ast_format_cap_has_type(cap, AST_FORMAT_SLINEAR)))
+#else
 	oldformat = format;
 	format &= AST_FORMAT_SLINEAR;
 	if (!format)
+#endif
 	{
-#if ASTERISK_VERSION_NUM >= 10800
+#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+		char buf[255];
+		ast_log (LOG_WARNING, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple (buf, 255, cap));
+#elif ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
 		ast_log (LOG_WARNING, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname (oldformat));
 #else
 		ast_log (LOG_WARNING, "Asked to get a channel of unsupported format '%d'\n", oldformat);

From aebd07348672cfd8f620a57aaa61e83d2e6e04dd Mon Sep 17 00:00:00 2001
From: Walter Doekes <walter+github@wjd.nu>
Date: Sat, 5 Sep 2015 17:03:52 +0200
Subject: [PATCH 03/15] Add more Asterisk 10 support.

Author: me, some time in the past.
Source: /~dexter/work/asterisk-chan-dongle/patch3.patch.txt
---
 chan_dongle.c | 19 +++++++++++++++++++
 chan_dongle.h |  3 +++
 channel.c     | 45 +++++++++++++++++++++++++++++++--------------
 channel.h     |  2 +-
 4 files changed, 54 insertions(+), 15 deletions(-)

diff --git a/chan_dongle.c b/chan_dongle.c
index e6e99ba..48dc1d3 100644
--- a/chan_dongle.c
+++ b/chan_dongle.c
@@ -39,6 +39,7 @@
 #include <asterisk.h>
 ASTERISK_FILE_VERSION(__FILE__, "$Rev: " PACKAGE_REVISION " $")
 
+#include <asterisk/version.h>
 #include <asterisk/stringfields.h>	/* AST_DECLARE_STRING_FIELDS for asterisk/manager.h */
 #include <asterisk/manager.h>
 #include <asterisk/dsp.h>
@@ -67,6 +68,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Rev: " PACKAGE_REVISION " $")
 
 EXPORT_DEF const char * const dev_state_strs[4] = { "stop", "restart", "remove", "start" };
 EXPORT_DEF public_state_t * gpublic;
+EXPORT_DEF struct ast_format chan_dongle_format;
+EXPORT_DEF struct ast_format_cap * chan_dongle_format_cap;
 
 
 static int public_state_init(struct public_state * state);
@@ -1659,6 +1662,16 @@ static int public_state_init(struct public_state * state)
 		rv = AST_MODULE_LOAD_FAILURE;
 		if(discovery_restart(state) == 0)
 		{
+#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+			/* set preferred capabilities */
+			ast_format_set(&chan_dongle_format, AST_FORMAT_SLINEAR, 0);
+			if (!(channel_tech.capabilities = ast_format_cap_alloc())) {
+				return AST_MODULE_LOAD_FAILURE;
+			}
+			ast_format_cap_add(channel_tech.capabilities, &chan_dongle_format);
+			chan_dongle_format_cap = channel_tech.capabilities;
+#endif
+
 			/* register our channel type */
 			if(ast_channel_register(&channel_tech) == 0)
 			{
@@ -1671,6 +1684,9 @@ static int public_state_init(struct public_state * state)
 			}
 			else
 			{
+#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+				channel_tech.capabilities = ast_format_cap_destroy(channel_tech.capabilities);
+#endif
 				ast_log (LOG_ERROR, "Unable to register channel class %s\n", channel_tech.type);
 			}
 			discovery_stop(state);
@@ -1698,6 +1714,9 @@ static void public_state_fini(struct public_state * state)
 {
 	/* First, take us out of the channel loop */
 	ast_channel_unregister (&channel_tech);
+#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+	channel_tech.capabilities = ast_format_cap_destroy(channel_tech.capabilities);
+#endif
 
 	/* Unregister the CLI & APP & MANAGER */
 
diff --git a/chan_dongle.h b/chan_dongle.h
index 0123e04..4783e5e 100644
--- a/chan_dongle.h
+++ b/chan_dongle.h
@@ -36,6 +36,9 @@ INLINE_DECL const char * dev_state2str_msg(dev_state_t state)
 	return enum2str(state, states, ITEMS_OF(states));
 }
 
+/* Only linear is allowed */
+EXPORT_DECL struct ast_format chan_dongle_format;
+EXPORT_DECL struct ast_format_cap * chan_dongle_format_cap;
 
 typedef enum {
 	RESTATE_TIME_NOW	= 0,
diff --git a/channel.c b/channel.c
index cfd926a..ea75931 100644
--- a/channel.c
+++ b/channel.c
@@ -103,17 +103,16 @@ static struct ast_channel * channel_request (attribute_unused const char * type,
 //   TODO: simplify by move common code to functions
 static struct ast_channel * channel_request (attribute_unused const char * type, format_t format, const struct ast_channel * requestor, void * data, int * cause)
 
-#else /* ASTERISK_VERSION_NUM < 10800 */
+#else /* 1.8- */
 /* TODO: add check when request 'holdother' what requestor is not on same device for 1.6 */
 
 static struct ast_channel * channel_request (attribute_unused const char * type, int format, void * data, int * cause)
 
-#endif /* ASTERISK_VERSION_NUM */
+#endif
 {
-#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
-#elif ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
+#if ASTERISK_VERSION_NUM >= 10800 && ASTERISK_VERSION_NUM < 100000 /* 1.8+ .. 10- */
 	format_t oldformat;
-#else
+#elif ASTERISK_VERSION_NUM < 10800 /* 1.8- */
 	int oldformat;
 	const struct ast_channel * requestor = NULL;
 #endif
@@ -132,7 +131,7 @@ static struct ast_channel * channel_request (attribute_unused const char * type,
 	}
 
 #if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
-	if (!(ast_format_cap_has_type(cap, AST_FORMAT_SLINEAR)))
+	if (!ast_format_cap_iscompatible(cap, &chan_dongle_format))
 #else
 	oldformat = format;
 	format &= AST_FORMAT_SLINEAR;
@@ -583,10 +582,12 @@ static void write_conference(struct pvt * pvt, const char * buffer, size_t lengt
 
 }
 
-#if ASTERISK_VERSION_NUM >= 10800
+#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+#define subclass_integer	subclass.integer
+#elif ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
 #define subclass_codec		subclass.codec
 #define subclass_integer	subclass.integer
-#else
+#else /* 1.8- */
 #define subclass_codec		subclass
 #define subclass_integer	subclass
 #endif
@@ -630,7 +631,11 @@ static struct ast_frame* channel_read (struct ast_channel* channel)
 		memset (&cpvt->a_read_frame, 0, sizeof (cpvt->a_read_frame));
 
 		cpvt->a_read_frame.frametype = AST_FRAME_VOICE;
-		cpvt->a_read_frame.subclass_codec= AST_FORMAT_SLINEAR;
+#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+		ast_format_copy(&cpvt->a_read_frame.subclass.format, &chan_dongle_format);
+#else
+		cpvt->a_read_frame.subclass_codec = AST_FORMAT_SLINEAR;
+#endif
 		cpvt->a_read_frame.data.ptr = cpvt->a_read_buf + AST_FRIENDLY_OFFSET;
 		cpvt->a_read_frame.offset = AST_FRIENDLY_OFFSET;
 		cpvt->a_read_frame.src = AST_MODULE;
@@ -744,7 +749,11 @@ static int channel_write (struct ast_channel* channel, struct ast_frame* f)
 	size_t count;
 	int gains[2];
 
+#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+	if (f->frametype != AST_FRAME_VOICE || f->subclass.format.id != AST_FORMAT_SLINEAR)
+#else /* 10- */
 	if (f->frametype != AST_FRAME_VOICE || f->subclass_codec != AST_FORMAT_SLINEAR)
+#endif
 	{
 		return 0;
 	}
@@ -1158,9 +1167,15 @@ EXPORT_DEF struct ast_channel* new_channel (struct pvt* pvt, int ast_state, cons
 
 			channel->tech_pvt	= cpvt;
 			channel->tech		= &channel_tech;
+#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+			ast_format_cap_add(channel->nativeformats, &chan_dongle_format);
+			ast_format_copy(&channel->writeformat, &chan_dongle_format);
+			ast_format_copy(&channel->readformat, &chan_dongle_format);
+#else /* 10- */
 			channel->nativeformats	= AST_FORMAT_SLINEAR;
 			channel->writeformat	= AST_FORMAT_SLINEAR;
 			channel->readformat	= AST_FORMAT_SLINEAR;
+#endif
 
 			if (ast_state == AST_STATE_RING)
 			{
@@ -1248,9 +1263,11 @@ EXPORT_DEF void start_local_channel (struct pvt* pvt, const char* exten, const c
 
 	snprintf (channel_name, sizeof (channel_name), "%s@%s", exten, CONF_SHARED(pvt, context));
 
-#if ASTERISK_VERSION_NUM >= 10800
+#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+	channel = ast_request ("Local", chan_dongle_format_cap, NULL, channel_name, &cause);
+#elif ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
 	channel = ast_request ("Local", AST_FORMAT_AUDIO_MASK, NULL, channel_name, &cause);
-#else
+#else /* 1.8- */
 	channel = ast_request ("Local", AST_FORMAT_AUDIO_MASK, channel_name, &cause);
 #endif
 	if (channel)
@@ -1335,7 +1352,6 @@ static int channel_func_read(struct ast_channel* channel, attribute_unused const
 static int channel_func_write(struct ast_channel* channel, const char* function, char* data, const char* value)
 {
 	struct cpvt* cpvt = channel->tech_pvt;
-	struct pvt* pvt;
 	call_state_t newstate, oldstate;
 	int ret = 0;
 
@@ -1344,7 +1360,6 @@ static int channel_func_write(struct ast_channel* channel, const char* function,
 		ast_log (LOG_WARNING, "call on unreferenced %s\n", channel->name);
 		return -1;
 	}
-	pvt = cpvt->pvt;
 
 	if (!strcasecmp(data, "callstate"))
 	{
@@ -1411,11 +1426,13 @@ static int channel_func_write(struct ast_channel* channel, const char* function,
 	return ret;
 }
 
-EXPORT_DEF const struct ast_channel_tech channel_tech =
+EXPORT_DEF struct ast_channel_tech channel_tech =
 {
 	.type			= "Dongle",
 	.description		= MODULE_DESCRIPTION,
+#if ASTERISK_VERSION_NUM < 100000 /* 10- */
 	.capabilities		= AST_FORMAT_SLINEAR,
+#endif
 	.requester		= channel_request,
 	.call			= channel_call,
 	.hangup			= channel_hangup,
diff --git a/channel.h b/channel.h
index d4ab5be..e62bc9d 100644
--- a/channel.h
+++ b/channel.h
@@ -19,7 +19,7 @@ typedef struct channel_var
 struct pvt;
 struct cpvt;
 
-EXPORT_DECL const struct ast_channel_tech channel_tech;
+EXPORT_DECL struct ast_channel_tech channel_tech;
 
 EXPORT_DECL struct ast_channel* new_channel (struct pvt * pvt, int ast_state, const char * cid_num, int call_idx, unsigned dir, unsigned state, const char * exten, const struct ast_channel * requestor);
 EXPORT_DECL int queue_control_channel (struct cpvt * cpvt, enum ast_control_frame_type control);

From 9108a966aa146487815f639f653cd0401e2849c5 Mon Sep 17 00:00:00 2001
From: Walter Doekes <walter+github@wjd.nu>
Date: Sat, 5 Sep 2015 17:21:25 +0200
Subject: [PATCH 04/15] Add Asterisk 11 support.

Author: me, in August 2013.
---
 app.c         |   3 +-
 ast_compat.h  |  56 ++++++++++++++++++++++
 at_response.c |   9 ++--
 chan_dongle.c |   5 +-
 chan_dongle.h |   4 ++
 channel.c     | 148 ++++++++++++++++++++++++++++++++++------------------------
 cli.c         |   6 ++-
 manager.c     |   4 ++
 8 files changed, 166 insertions(+), 69 deletions(-)
 create mode 100644 ast_compat.h

diff --git a/app.c b/app.c
index c0965ff..a46fc8d 100644
--- a/app.c
+++ b/app.c
@@ -18,7 +18,8 @@
 #include <asterisk/app.h>	/* AST_DECLARE_APP_ARGS() ... */
 #include <asterisk/pbx.h>	/* pbx_builtin_setvar_helper() */
 #include <asterisk/module.h>	/* ast_register_application2() ast_unregister_application() */
-#include <asterisk/version.h>	/* ASTERISK_VERSION_NUM */
+
+#include "ast_compat.h"		/* asterisk compatibility fixes */
 
 #include "app.h"		/* app_register() app_unregister() */
 #include "chan_dongle.h"	/* struct pvt */
diff --git a/ast_compat.h b/ast_compat.h
new file mode 100644
index 0000000..c22b75e
--- /dev/null
+++ b/ast_compat.h
@@ -0,0 +1,56 @@
+#ifndef CHAN_DONGLE_AST_COMPAT_H_INCLUDED
+#define CHAN_DONGLE_AST_COMPAT_H_INCLUDED
+
+#ifndef ASTERISK_VERSION_NUM
+#error ASTERISK_VERSION_NUM is not set. Please re-run configure, \
+	prefixed like this: CPPFLAGS=-DASTERISK_VERSION_NUM=100501 \
+	./configure (where 100501 is asterisk version 10.5.1).
+#endif
+
+#include <asterisk/channel.h>
+
+/* Asterisk 11+ channel opaqification */
+#if ASTERISK_VERSION_NUM < 110000
+
+/* channel->name */
+static inline const char *ast_channel_name(const struct ast_channel *chan) { return chan->name; }
+
+/* channel->_state / channel->state */
+static inline enum ast_channel_state ast_channel_state(const struct ast_channel *chan) { return chan->_state; }
+
+/* channel->fdno */
+static inline int ast_channel_fdno(const struct ast_channel *chan) { return chan->fdno; }
+
+/* channel->tech */
+static inline const struct ast_channel_tech *ast_channel_tech(const struct ast_channel *chan) { return chan->tech; }
+static inline void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value) { chan->tech = value; }
+
+static inline void *ast_channel_tech_pvt(const struct ast_channel *chan) { return chan->tech_pvt; }
+static inline void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value) { chan->tech_pvt = value; }
+
+/* channel->rings */
+static inline int ast_channel_rings(const struct ast_channel *chan) { return chan->rings; }
+static inline void ast_channel_rings_set(struct ast_channel *chan, int value) { chan->rings = value; }
+
+/* ast_string_field_set(channel, language, ...) */
+static inline void ast_channel_language_set(struct ast_channel *chan, const char *value) { ast_string_field_set(chan, language, value); }
+
+/* channel->connected */
+static inline struct ast_party_connected_line *ast_channel_connected(struct ast_channel *chan) { return &chan->connected; }
+
+/* channel->linkedid */
+static inline const char *ast_channel_linkedid(const struct ast_channel *chan) { return chan->linkedid; }
+
+/* channel->hangupcause */
+static inline void ast_channel_hangupcause_set(struct ast_channel *chan, int value) { chan->hangupcause = value; }
+
+#if ASTERISK_VERSION_NUM >= 100000
+/* channel->*format* */
+static inline struct ast_format_cap *ast_channel_nativeformats(const struct ast_channel *chan) { return chan->nativeformats; }
+static inline struct ast_format ast_channel_readformat(const struct ast_channel *chan) { return chan->readformat; }
+static inline struct ast_format ast_channel_writeformat(const struct ast_channel *chan) { return chan->writeformat; }
+#endif
+
+#endif
+
+#endif /* CHAN_DONGLE_AST_COMPAT_H_INCLUDED */
diff --git a/at_response.c b/at_response.c
index e66be46..ad3e056 100644
--- a/at_response.c
+++ b/at_response.c
@@ -16,6 +16,8 @@
 #include <asterisk/logger.h>			/* ast_debug() */
 #include <asterisk/pbx.h>			/* ast_pbx_start() */
 
+#include "ast_compat.h"				/* asterisk compatibility fixes */
+
 #include "at_response.h"
 #include "mutils.h"				/* STRLEN() */
 #include "at_queue.h"
@@ -851,14 +853,14 @@ static int start_pbx(struct pvt* pvt, const char * number, int call_idx, call_st
 
 		return -1;
 	}
-	cpvt = channel->tech_pvt;
+	cpvt = ast_channel_tech_pvt(channel);
 // FIXME: not execute if channel_new() failed
 	CPVT_SET_FLAGS(cpvt, CALL_FLAG_NEED_HANGUP);
 
 	// ast_pbx_start() usually failed if asterisk.conf minmemfree set too low, try drop buffer cache sync && echo 3 > /proc/sys/vm/drop_caches
 	if (ast_pbx_start (channel))
 	{
-		channel->tech_pvt = NULL;
+		ast_channel_tech_pvt_set(channel, NULL);
 		cpvt_free(cpvt);
 
 		ast_hangup (channel);
@@ -920,8 +922,7 @@ static int at_response_clcc (struct pvt* pvt, char* str)
 								if(cpvt->channel)
 								{
 									/* FIXME: unprotected channel access */
-									cpvt->channel->rings += pvt->rings;
-									pvt->rings = 0;
+									ast_channel_rings_set(cpvt->channel, ast_channel_rings(cpvt->channel) + pvt->rings);
 								}
 							}
 							if(state != cpvt->state)
diff --git a/chan_dongle.c b/chan_dongle.c
index 48dc1d3..dba5a49 100644
--- a/chan_dongle.c
+++ b/chan_dongle.c
@@ -39,7 +39,6 @@
 #include <asterisk.h>
 ASTERISK_FILE_VERSION(__FILE__, "$Rev: " PACKAGE_REVISION " $")
 
-#include <asterisk/version.h>
 #include <asterisk/stringfields.h>	/* AST_DECLARE_STRING_FIELDS for asterisk/manager.h */
 #include <asterisk/manager.h>
 #include <asterisk/dsp.h>
@@ -53,6 +52,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Rev: " PACKAGE_REVISION " $")
 #include <fcntl.h>			/* O_RDWR O_NOCTTY */
 #include <signal.h>			/* SIGURG */
 
+#include "ast_compat.h"			/* asterisk compatibility fixes */
+
 #include "chan_dongle.h"
 #include "at_response.h"		/* at_res_t */
 #include "at_queue.h"			/* struct at_queue_task_cmd at_queue_head_cmd() */
@@ -68,8 +69,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Rev: " PACKAGE_REVISION " $")
 
 EXPORT_DEF const char * const dev_state_strs[4] = { "stop", "restart", "remove", "start" };
 EXPORT_DEF public_state_t * gpublic;
+#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
 EXPORT_DEF struct ast_format chan_dongle_format;
 EXPORT_DEF struct ast_format_cap * chan_dongle_format_cap;
+#endif
 
 
 static int public_state_init(struct public_state * state);
diff --git a/chan_dongle.h b/chan_dongle.h
index 4783e5e..b3adab7 100644
--- a/chan_dongle.h
+++ b/chan_dongle.h
@@ -16,6 +16,8 @@
 #include <asterisk/lock.h>
 #include <asterisk/linkedlists.h>
 
+#include <ast_compat.h>
+
 #include "mixbuffer.h"				/* struct mixbuffer */
 //#include "ringbuffer.h"				/* struct ringbuffer */
 #include "cpvt.h"				/* struct cpvt */
@@ -36,9 +38,11 @@ INLINE_DECL const char * dev_state2str_msg(dev_state_t state)
 	return enum2str(state, states, ITEMS_OF(states));
 }
 
+#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
 /* Only linear is allowed */
 EXPORT_DECL struct ast_format chan_dongle_format;
 EXPORT_DECL struct ast_format_cap * chan_dongle_format_cap;
+#endif
 
 typedef enum {
 	RESTATE_TIME_NOW	= 0,
diff --git a/channel.c b/channel.c
index ea75931..73e4033 100644
--- a/channel.c
+++ b/channel.c
@@ -12,6 +12,10 @@
 #include <config.h>
 #endif /* HAVE_CONFIG_H */
 
+#ifndef ASTERISK_VERSION_NUM
+#error ASTERISK_VERSION_NUM is not set, please supply -D ASTERISK_VERSION_NUM=100501 for version 10.5.1
+#endif
+
 #include <asterisk.h>
 #include <asterisk/dsp.h>			/* ast_dsp_digitreset() */
 #include <asterisk/pbx.h>			/* pbx_builtin_setvar_helper() */
@@ -20,7 +24,8 @@
 #include <asterisk/musiconhold.h>		/* ast_moh_start() ast_moh_stop() */
 #include <asterisk/lock.h>			/* AST_MUTEX_DEFINE_STATIC */
 #include <asterisk/timing.h>			/* ast_timer_fd() ast_timer_set_rate() ast_timer_ack() */
-#include <asterisk/version.h>			/* ASTERISK_VERSION_NUM */
+
+#include "ast_compat.h"
 
 #include "channel.h"
 #include "chan_dongle.h"
@@ -29,6 +34,7 @@
 #include "at_queue.h"				/* write_all() TODO: move out */
 #include "manager.h"				/* manager_event_call_state_change() */
 
+
 static char silence_frame[FRAME_SIZE];
 
 #/* */
@@ -90,25 +96,23 @@ EXPORT_DEF int channels_loop(struct pvt * pvt, const struct ast_channel * reques
 	/* FIXME: requestor may be just proxy/masquerade for real channel */
 	//	use ast_bridged_channel(chan) ?
 	//	use requestor->tech->get_base_channel() ?
-	if(requestor && requestor->tech == &channel_tech && requestor->tech_pvt && ((struct cpvt*)requestor->tech_pvt)->pvt == pvt)
+	struct cpvt *cpvt = ast_channel_tech_pvt(requestor);
+	if(requestor && ast_channel_tech(requestor) == &channel_tech && cpvt && cpvt->pvt == pvt)
 		return 1;
 	return 0;
 }
 
-#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
-
+// TODO: simplify by move common code to functions
+/* TODO: add check when request 'holdother' what requestor is not on same device for 1.6 */
+#if ASTERISK_VERSION_NUM >= 110000 /* 11+ */
+static struct ast_channel * channel_request (attribute_unused const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
+#elif ASTERISK_VERSION_NUM >= 100000 /* 10+ */
 static struct ast_channel * channel_request (attribute_unused const char * type, struct ast_format_cap * cap, const struct ast_channel *requestor, void * data, int * cause)
-
 #elif ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
-//   TODO: simplify by move common code to functions
 static struct ast_channel * channel_request (attribute_unused const char * type, format_t format, const struct ast_channel * requestor, void * data, int * cause)
-
-#else /* 1.8- */
-/* TODO: add check when request 'holdother' what requestor is not on same device for 1.6 */
-
+#else /* #if ASTERISK_VERSION_NUM < 10800 */
 static struct ast_channel * channel_request (attribute_unused const char * type, int format, void * data, int * cause)
-
-#endif
+#endif /* #if ASTERISK_VERSION_NUM < 10800 */
 {
 #if ASTERISK_VERSION_NUM >= 10800 && ASTERISK_VERSION_NUM < 100000 /* 1.8+ .. 10- */
 	format_t oldformat;
@@ -133,11 +137,11 @@ static struct ast_channel * channel_request (attribute_unused const char * type,
 #if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
 	if (!ast_format_cap_iscompatible(cap, &chan_dongle_format))
 #else
-	oldformat = format;
-	format &= AST_FORMAT_SLINEAR;
-	if (!format)
+        oldformat = format;
+        format &= AST_FORMAT_SLINEAR;
+        if (!format)
 #endif
-	{
+        {
 #if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
 		char buf[255];
 		ast_log (LOG_WARNING, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple (buf, 255, cap));
@@ -182,9 +186,13 @@ static struct ast_channel * channel_request (attribute_unused const char * type,
 }
 
 #/* */
+#if ASTERISK_VERSION_NUM >= 110000 /* 11+ */
+static int channel_call (struct ast_channel* channel, const char *dest, attribute_unused int timeout)
+#else
 static int channel_call (struct ast_channel* channel, char* dest, attribute_unused int timeout)
+#endif
 {
-	struct cpvt* cpvt = channel->tech_pvt;
+	struct cpvt* cpvt = ast_channel_tech_pvt(channel);
 	struct pvt* pvt;
 	char* dest_dev;
 	const char* dest_num;
@@ -193,7 +201,7 @@ static int channel_call (struct ast_channel* channel, char* dest, attribute_unus
 
 	if(!cpvt || cpvt->channel != channel || !cpvt->pvt)
 	{
-		ast_log (LOG_WARNING, "call on unreferenced %s\n", channel->name);
+		ast_log (LOG_WARNING, "call on unreferenced %s\n", ast_channel_name(channel));
 		return -1;
 	}
 	pvt = cpvt->pvt;
@@ -203,9 +211,9 @@ static int channel_call (struct ast_channel* channel, char* dest, attribute_unus
 	if(parse_dial_string(dest_dev, &dest_num, &opts))
 		return -1;
 
-	if ((channel->_state != AST_STATE_DOWN) && (channel->_state != AST_STATE_RESERVED))
+	if ((ast_channel_state(channel) != AST_STATE_DOWN) && (ast_channel_state(channel) != AST_STATE_RESERVED))
 	{
-		ast_log (LOG_WARNING, "channel_call called on %s, neither down nor reserved\n", channel->name);
+		ast_log (LOG_WARNING, "channel_call called on %s, neither down nor reserved\n", ast_channel_name(channel));
 		return -1;
 	}
 
@@ -220,14 +228,14 @@ static int channel_call (struct ast_channel* channel, char* dest, attribute_unus
 	}
 	CPVT_SET_FLAGS(cpvt, opts);
 
-	ast_debug (1, "[%s] Calling %s on %s\n", PVT_ID(pvt), dest, channel->name);
+	ast_debug (1, "[%s] Calling %s on %s\n", PVT_ID(pvt), dest, ast_channel_name(channel));
 
 	if (CONF_SHARED(pvt, usecallingpres))
 	{
 		if (CONF_SHARED(pvt, callingpres) < 0)
 		{
 #if ASTERISK_VERSION_NUM >= 10800
-			clir = channel->connected.id.number.presentation;
+			clir = ast_channel_connected(channel)->id.number.presentation;
 #else
 			clir = channel->cid.cid_pres;
 #endif
@@ -339,7 +347,7 @@ static void activate_call(struct cpvt* cpvt)
 #/* we has 2 case of call this function, when local side want terminate call and when called for cleanup after remote side alreay terminate call, CEND received and cpvt destroyed */
 static int channel_hangup (struct ast_channel* channel)
 {
-	struct cpvt* cpvt = channel->tech_pvt;
+	struct cpvt* cpvt = ast_channel_tech_pvt(channel);
 	struct pvt* pvt;
 
 	/* its possible call with channel w/o tech_pvt */
@@ -368,7 +376,7 @@ static int channel_hangup (struct ast_channel* channel)
 	}
 
 	/* drop channel -> cpvt reference */
-	channel->tech_pvt = NULL;
+	ast_channel_tech_pvt_set(channel, NULL);
 
 	ast_module_unref (self_module());
 	ast_setstate (channel, AST_STATE_DOWN);
@@ -379,12 +387,12 @@ static int channel_hangup (struct ast_channel* channel)
 #/* */
 static int channel_answer (struct ast_channel* channel)
 {
-	struct cpvt* cpvt = channel->tech_pvt;
+	struct cpvt* cpvt = ast_channel_tech_pvt(channel);
 	struct pvt* pvt;
 
 	if(!cpvt || cpvt->channel != channel || !cpvt->pvt)
 	{
-		ast_log (LOG_WARNING, "call on unreferenced %s\n", channel->name);
+		ast_log (LOG_WARNING, "call on unreferenced %s\n", ast_channel_name(channel));
 		return 0;
 	}
 	pvt = cpvt->pvt;
@@ -408,13 +416,13 @@ static int channel_answer (struct ast_channel* channel)
 #/* */
 static int channel_digit_begin (struct ast_channel* channel, char digit)
 {
-	struct cpvt* cpvt = channel->tech_pvt;
+	struct cpvt* cpvt = ast_channel_tech_pvt(channel);
 	struct pvt* pvt;
 	int rv;
 
 	if(!cpvt || cpvt->channel != channel || !cpvt->pvt)
 	{
-		ast_log (LOG_WARNING, "call on unreferenced %s\n", channel->name);
+		ast_log (LOG_WARNING, "call on unreferenced %s\n", ast_channel_name(channel));
 		return -1;
 	}
 	pvt = cpvt->pvt;
@@ -582,20 +590,21 @@ static void write_conference(struct pvt * pvt, const char * buffer, size_t lengt
 
 }
 
+
 #if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
-#define subclass_integer	subclass.integer
+#define subclass_integer       subclass.integer
 #elif ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
-#define subclass_codec		subclass.codec
-#define subclass_integer	subclass.integer
+#define subclass_codec         subclass.codec
+#define subclass_integer       subclass.integer
 #else /* 1.8- */
-#define subclass_codec		subclass
-#define subclass_integer	subclass
+#define subclass_codec         subclass
+#define subclass_integer       subclass
 #endif
 
 #/* */
 static struct ast_frame* channel_read (struct ast_channel* channel)
 {
-	struct cpvt*		cpvt = channel->tech_pvt;
+	struct cpvt*		cpvt = ast_channel_tech_pvt(channel);
 	struct pvt*		pvt;
 	struct ast_frame*	f = &ast_null_frame;
 	ssize_t			res;
@@ -619,7 +628,7 @@ static struct ast_frame* channel_read (struct ast_channel* channel)
 		goto e_return;
 	}
 
-	if (pvt->a_timer && channel->fdno == 1)
+	if (pvt->a_timer && ast_channel_fdno(channel) == 1)
 	{
 		ast_timer_ack (pvt->a_timer, 1);
 		timing_write (pvt);
@@ -744,7 +753,7 @@ static struct ast_frame* channel_read (struct ast_channel* channel)
 #/* */
 static int channel_write (struct ast_channel* channel, struct ast_frame* f)
 {
-	struct cpvt* cpvt = channel->tech_pvt;
+	struct cpvt* cpvt = ast_channel_tech_pvt(channel);
 	struct pvt* pvt;
 	size_t count;
 	int gains[2];
@@ -760,7 +769,7 @@ static int channel_write (struct ast_channel* channel, struct ast_frame* f)
 
 	if(!cpvt || cpvt->channel != channel || !cpvt->pvt)
 	{
-		ast_log (LOG_WARNING, "call on unreferenced %s\n", channel->name);
+		ast_log (LOG_WARNING, "call on unreferenced %s\n", ast_channel_name(channel));
 		return 0;
 	}
 
@@ -785,14 +794,16 @@ static int channel_write (struct ast_channel* channel, struct ast_frame* f)
 	if(CPVT_TEST_FLAG(cpvt, CALL_FLAG_MULTIPARTY) && !CPVT_TEST_FLAG(cpvt, CALL_FLAG_BRIDGE_CHECK))
 	{
 		struct ast_channel* bridged = ast_bridged_channel(channel);
+		struct cpvt *tmp_cpvt;
 
 		CPVT_SET_FLAGS(cpvt, CALL_FLAG_BRIDGE_CHECK);
 
-		if(bridged && bridged->tech == &channel_tech && bridged->tech_pvt && ((struct cpvt*)bridged->tech_pvt)->pvt == pvt)
+		tmp_cpvt = ast_channel_tech_pvt(bridged);
+		if(bridged && ast_channel_tech(bridged) == &channel_tech && tmp_cpvt && tmp_cpvt->pvt == pvt)
 		{
 			CPVT_SET_FLAGS(cpvt, CALL_FLAG_BRIDGE_LOOP);
-			CPVT_SET_FLAGS((struct cpvt*)bridged->tech_pvt, CALL_FLAG_BRIDGE_LOOP);
-			ast_log (LOG_WARNING, "[%s] Bridged channels %s and %s working on same device, discard writes to avoid voice loop\n", PVT_ID(pvt), channel->name, bridged->name);
+			CPVT_SET_FLAGS((struct cpvt*)ast_channel_tech_pvt(bridged), CALL_FLAG_BRIDGE_LOOP);
+			ast_log(LOG_WARNING, "[%s] Bridged channels %s and %s working on same device, discard writes to avoid voice loop\n", PVT_ID(pvt), ast_channel_name(channel), ast_channel_name(bridged));
 			goto e_return;
 		}
 	}
@@ -915,12 +926,12 @@ static int channel_write (struct ast_channel* channel, struct ast_frame* f)
 #/* */
 static int channel_fixup (struct ast_channel* oldchannel, struct ast_channel* newchannel)
 {
-	struct cpvt * cpvt = newchannel->tech_pvt;
+	struct cpvt * cpvt = ast_channel_tech_pvt(newchannel);
 	struct pvt* pvt;
 
 	if (!cpvt || !cpvt->pvt)
 	{
-		ast_log (LOG_WARNING, "call on unreferenced %s\n", newchannel->name);
+		ast_log (LOG_WARNING, "call on unreferenced %s\n", ast_channel_name(newchannel));
 		return -1;
 	}
 	pvt = cpvt->pvt;
@@ -936,7 +947,11 @@ static int channel_fixup (struct ast_channel* oldchannel, struct ast_channel* ne
 }
 
 #/* FIXME: must modify in conjuction with state on call not whole device? */
+#if ASTERISK_VERSION_NUM >= 110000 /* 11+ */
+static int channel_devicestate (const char *data)
+#else
 static int channel_devicestate (void* data)
+#endif
 {
 	char*	device;
 	struct pvt*	pvt;
@@ -971,7 +986,7 @@ static int channel_indicate (struct ast_channel* channel, int condition, const v
 {
 	int res = 0;
 
-	ast_debug (1, "[%s] Requested indication %d\n", channel->name, condition);
+	ast_debug (1, "[%s] Requested indication %d\n", ast_channel_name(channel), condition);
 
 	switch (condition)
 	{
@@ -1000,7 +1015,7 @@ static int channel_indicate (struct ast_channel* channel, int condition, const v
 			break;
 
 		default:
-			ast_log (LOG_WARNING, "[%s] Don't know how to indicate condition %d\n", channel->name, condition);
+			ast_log (LOG_WARNING, "[%s] Don't know how to indicate condition %d\n", ast_channel_name(channel), condition);
 			res = -1;
 			break;
 	}
@@ -1112,7 +1127,7 @@ EXPORT_DEF void change_channel_state(struct cpvt * cpvt, unsigned newstate, int
 
 
 					/* drop channel -> cpvt reference */
-					channel->tech_pvt = NULL;
+					ast_channel_tech_pvt_set(channel, NULL);
 					cpvt_free(cpvt);
 					if (queue_hangup (channel, cause))
 					{
@@ -1139,7 +1154,7 @@ static void set_channel_vars(struct pvt* pvt, struct ast_channel* channel)
 		{ "DONGLENUMBER", pvt->subscriber_number },
 	};
 
-	ast_string_field_set (channel, language, CONF_SHARED(pvt, language));
+	ast_channel_language_set(channel, CONF_SHARED(pvt, language));
 
 	for(idx = 0; idx < ITEMS_OF(dev_vars); ++idx)
 		pbx_builtin_setvar_helper (channel, dev_vars[idx].name, dev_vars[idx].value);
@@ -1156,7 +1171,7 @@ EXPORT_DEF struct ast_channel* new_channel (struct pvt* pvt, int ast_state, cons
 	if (cpvt)
 	{
 #if ASTERISK_VERSION_NUM >= 10800
-		channel = ast_channel_alloc (1, ast_state, cid_num, PVT_ID(pvt), NULL, dnid, CONF_SHARED(pvt, context), requestor ? requestor->linkedid : NULL, 0, "%s/%s-%02u%08lx", channel_tech.type, PVT_ID(pvt), call_idx, pvt->channel_instanse);
+		channel = ast_channel_alloc (1, ast_state, cid_num, PVT_ID(pvt), NULL, dnid, CONF_SHARED(pvt, context), requestor ? ast_channel_linkedid(requestor) : NULL, 0, "%s/%s-%02u%08lx", channel_tech.type, PVT_ID(pvt), call_idx, pvt->channel_instanse);
 #else
 		channel = ast_channel_alloc (1, ast_state, cid_num, PVT_ID(pvt), NULL, dnid, CONF_SHARED(pvt, context), 0, "%s/%s-%02u%08lx", channel_tech.type, PVT_ID(pvt), call_idx, pvt->channel_instanse);
 #endif
@@ -1165,12 +1180,18 @@ EXPORT_DEF struct ast_channel* new_channel (struct pvt* pvt, int ast_state, cons
 			cpvt->channel = channel;
 			pvt->channel_instanse++;
 
-			channel->tech_pvt	= cpvt;
-			channel->tech		= &channel_tech;
-#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
-			ast_format_cap_add(channel->nativeformats, &chan_dongle_format);
-			ast_format_copy(&channel->writeformat, &chan_dongle_format);
-			ast_format_copy(&channel->readformat, &chan_dongle_format);
+			ast_channel_tech_pvt_set(channel, cpvt);
+			ast_channel_tech_set(channel, &channel_tech);
+
+
+#if ASTERISK_VERSION_NUM >= 110000 /* 11+ */
+			ast_format_set(ast_channel_readformat(channel), AST_FORMAT_SLINEAR, 0);
+			ast_format_set(ast_channel_writeformat(channel), AST_FORMAT_SLINEAR, 0);
+			ast_format_cap_set(ast_channel_nativeformats(channel), ast_channel_writeformat(channel));
+#elif ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+			ast_format_set(&channel->readformat, AST_FORMAT_SLINEAR, 0);
+			ast_format_set(&channel->writeformat, AST_FORMAT_SLINEAR, 0);
+			ast_format_cap_set(channel->nativeformats, &channel->writeformat);
 #else /* 10- */
 			channel->nativeformats	= AST_FORMAT_SLINEAR;
 			channel->writeformat	= AST_FORMAT_SLINEAR;
@@ -1179,7 +1200,7 @@ EXPORT_DEF struct ast_channel* new_channel (struct pvt* pvt, int ast_state, cons
 
 			if (ast_state == AST_STATE_RING)
 			{
-				channel->rings = 1;
+				ast_channel_rings_set(channel, 1);
 			}
 
 			set_channel_vars(pvt, channel);
@@ -1246,8 +1267,9 @@ EXPORT_DEF int queue_hangup(struct ast_channel* channel, int hangupcause)
 	int rv = 0;
 	if(channel)
 	{
-		if (hangupcause != 0)
-			channel->hangupcause = hangupcause;
+		if (hangupcause != 0) {
+			ast_channel_hangupcause_set(channel, hangupcause);
+		}
 
 		rv = ast_queue_hangup (channel);
 	}
@@ -1267,7 +1289,7 @@ EXPORT_DEF void start_local_channel (struct pvt* pvt, const char* exten, const c
 	channel = ast_request ("Local", chan_dongle_format_cap, NULL, channel_name, &cause);
 #elif ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
 	channel = ast_request ("Local", AST_FORMAT_AUDIO_MASK, NULL, channel_name, &cause);
-#else /* 1.8- */
+#else
 	channel = ast_request ("Local", AST_FORMAT_AUDIO_MASK, channel_name, &cause);
 #endif
 	if (channel)
@@ -1294,13 +1316,13 @@ EXPORT_DEF void start_local_channel (struct pvt* pvt, const char* exten, const c
 #/* */
 static int channel_func_read(struct ast_channel* channel, attribute_unused const char* function, char* data, char* buf, size_t len)
 {
-	struct cpvt* cpvt = channel->tech_pvt;
+	struct cpvt* cpvt = ast_channel_tech_pvt(channel);
 	struct pvt* pvt;
 	int ret = 0;
 
 	if(!cpvt || !cpvt->pvt)
 	{
-		ast_log (LOG_WARNING, "call on unreferenced %s\n", channel->name);
+		ast_log (LOG_WARNING, "call on unreferenced %s\n", ast_channel_name(channel));
 		return -1;
 	}
 	pvt = cpvt->pvt;
@@ -1351,15 +1373,17 @@ static int channel_func_read(struct ast_channel* channel, attribute_unused const
 #/* */
 static int channel_func_write(struct ast_channel* channel, const char* function, char* data, const char* value)
 {
-	struct cpvt* cpvt = channel->tech_pvt;
+	struct cpvt* cpvt = ast_channel_tech_pvt(channel);
+	struct pvt* pvt;
 	call_state_t newstate, oldstate;
 	int ret = 0;
 
 	if(!cpvt || !cpvt->pvt)
 	{
-		ast_log (LOG_WARNING, "call on unreferenced %s\n", channel->name);
+		ast_log (LOG_WARNING, "call on unreferenced %s\n", ast_channel_name(channel));
 		return -1;
 	}
+	pvt = cpvt->pvt;
 
 	if (!strcasecmp(data, "callstate"))
 	{
@@ -1431,7 +1455,7 @@ EXPORT_DEF struct ast_channel_tech channel_tech =
 	.type			= "Dongle",
 	.description		= MODULE_DESCRIPTION,
 #if ASTERISK_VERSION_NUM < 100000 /* 10- */
-	.capabilities		= AST_FORMAT_SLINEAR,
+	.capabilities           = AST_FORMAT_SLINEAR,
 #endif
 	.requester		= channel_request,
 	.call			= channel_call,
diff --git a/cli.c b/cli.c
index d0b1918..4c25562 100644
--- a/cli.c
+++ b/cli.c
@@ -12,10 +12,14 @@
 #include <config.h>
 #endif /* HAVE_CONFIG_H */
 
+#ifndef ASTERISK_VERSION_NUM
+#error ASTERISK_VERSION_NUM is not set, please supply \
+	-D ASTERISK_VERSION_NUM=100501 for version 10.5.1
+#endif
+
 #include <asterisk.h>
 #include <asterisk/cli.h>			/* struct ast_cli_entry; struct ast_cli_args */
 #include <asterisk/callerid.h>			/* ast_describe_caller_presentation() */
-#include <asterisk/version.h>			/* ASTERISK_VERSION_NUM */
 
 #include "cli.h"
 #include "chan_dongle.h"			/* devices */
diff --git a/manager.c b/manager.c
index ceda3a2..4f9e962 100644
--- a/manager.c
+++ b/manager.c
@@ -733,7 +733,11 @@ EXPORT_DEF void manager_register()
 	unsigned i;
 	for(i = 0; i < ITEMS_OF(dcm); i++)
 	{
+#if ASTERISK_VERSION_NUM >= 110000
+		ast_manager_register2 (dcm[i].name, dcm[i].authority, dcm[i].func, NULL, dcm[i].brief, dcm[i].desc);
+#else
 		ast_manager_register2 (dcm[i].name, dcm[i].authority, dcm[i].func, dcm[i].brief, dcm[i].desc);
+#endif
 	}
 }
 

From 46cc1dd054c533e48cdba68cbde2935e4365e4e4 Mon Sep 17 00:00:00 2001
From: Walter Doekes <walter+github@wjd.nu>
Date: Sat, 5 Sep 2015 17:40:51 +0200
Subject: [PATCH 05/15] Add .gitignore.

---
 .gitignore | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 .gitignore

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9170b95
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,20 @@
+*.swp
+
+*.o
+*.o.d
+
+/chan_dongle.so
+
+/Makefile
+/aclocal.m4
+/autom4te.cache
+/compile
+/config.guess
+/config.h
+/config.log
+/config.status
+/config.sub
+/configure
+/install-sh
+/missing
+/stamp-h1

From 50110f333c0f10d1237e4c6947f9dd11f476caf3 Mon Sep 17 00:00:00 2001
From: Walter Doekes <walter+github@wjd.nu>
Date: Sat, 5 Sep 2015 22:53:17 +0200
Subject: [PATCH 06/15] Add Asterisk 13 support.

Author: novaktmp, 2014-12-01 17:42:52
Source: https://forum.openwrt.org/viewtopic.php?id=54343

Slight adaptations by me.
---
 at_response.c |  13 ++++++-
 chan_dongle.c |  33 ++++++++++++++---
 chan_dongle.h |   3 +-
 channel.c     | 114 +++++++++++++++++++++++++++++++++++++++-------------------
 channel.h     |   4 +++
 manager.c     |   9 ++++-
 pdu.c         |   2 +-
 7 files changed, 133 insertions(+), 45 deletions(-)

diff --git a/at_response.c b/at_response.c
index ad3e056..e8a35b6 100644
--- a/at_response.c
+++ b/at_response.c
@@ -840,7 +840,11 @@ static int start_pbx(struct pvt* pvt, const char * number, int call_idx, call_st
 	struct cpvt* cpvt;
 
 	/* TODO: pass also Subscriber number or other DID info for exten  */
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+	struct ast_channel * channel = new_channel (pvt, AST_STATE_RING, number, call_idx, CALL_DIR_INCOMING, state, pvt->has_subscriber_number ? pvt->subscriber_number : CONF_SHARED(pvt, exten), NULL, NULL);
+#else
 	struct ast_channel * channel = new_channel (pvt, AST_STATE_RING, number, call_idx, CALL_DIR_INCOMING, state, pvt->has_subscriber_number ? pvt->subscriber_number : CONF_SHARED(pvt, exten), NULL);
+#endif
 
 	if (!channel)
 	{
@@ -853,11 +857,15 @@ static int start_pbx(struct pvt* pvt, const char * number, int call_idx, call_st
 
 		return -1;
 	}
+
 	cpvt = ast_channel_tech_pvt(channel);
 // FIXME: not execute if channel_new() failed
 	CPVT_SET_FLAGS(cpvt, CALL_FLAG_NEED_HANGUP);
 
 	// ast_pbx_start() usually failed if asterisk.conf minmemfree set too low, try drop buffer cache sync && echo 3 > /proc/sys/vm/drop_caches
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+	ast_channel_unlock(channel);
+#endif
 	if (ast_pbx_start (channel))
 	{
 		ast_channel_tech_pvt_set(channel, NULL);
@@ -922,7 +930,10 @@ static int at_response_clcc (struct pvt* pvt, char* str)
 								if(cpvt->channel)
 								{
 									/* FIXME: unprotected channel access */
-									ast_channel_rings_set(cpvt->channel, ast_channel_rings(cpvt->channel) + pvt->rings);
+									int rings = ast_channel_rings(cpvt->channel);
+									rings += pvt->rings;
+									ast_channel_rings_set(cpvt->channel, rings);
+									pvt->rings = 0;
 								}
 							}
 							if(state != cpvt->state)
diff --git a/chan_dongle.c b/chan_dongle.c
index dba5a49..84eef5c 100644
--- a/chan_dongle.c
+++ b/chan_dongle.c
@@ -45,6 +45,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Rev: " PACKAGE_REVISION " $")
 #include <asterisk/callerid.h>
 #include <asterisk/module.h>		/* AST_MODULE_LOAD_DECLINE ... */
 #include <asterisk/timing.h>		/* ast_timer_open() ast_timer_fd() */
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+#include <asterisk/stasis_channels.h>
+#include <asterisk/format_cache.h>
+#endif
 
 #include <sys/stat.h>			/* S_IRUSR | S_IRGRP | S_IROTH */
 #include <termios.h>			/* struct termios tcgetattr() tcsetattr()  */
@@ -69,12 +73,11 @@ ASTERISK_FILE_VERSION(__FILE__, "$Rev: " PACKAGE_REVISION " $")
 
 EXPORT_DEF const char * const dev_state_strs[4] = { "stop", "restart", "remove", "start" };
 EXPORT_DEF public_state_t * gpublic;
-#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+#if ASTERISK_VERSION_NUM >= 100000 && ASTERISK_VERSION_NUM < 130000 /* 10+..13- */
 EXPORT_DEF struct ast_format chan_dongle_format;
 EXPORT_DEF struct ast_format_cap * chan_dongle_format_cap;
 #endif
 
-
 static int public_state_init(struct public_state * state);
 
 
@@ -1665,8 +1668,15 @@ static int public_state_init(struct public_state * state)
 		rv = AST_MODULE_LOAD_FAILURE;
 		if(discovery_restart(state) == 0)
 		{
-#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+
 			/* set preferred capabilities */
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+			if (!(channel_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
+				return AST_MODULE_LOAD_FAILURE;
+			}
+			ast_format_cap_append(channel_tech.capabilities, ast_format_slin, 0);
+			//chan_dongle_format_cap = channel_tech.capabilities;
+#elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
 			ast_format_set(&chan_dongle_format, AST_FORMAT_SLINEAR, 0);
 			if (!(channel_tech.capabilities = ast_format_cap_alloc())) {
 				return AST_MODULE_LOAD_FAILURE;
@@ -1687,7 +1697,10 @@ static int public_state_init(struct public_state * state)
 			}
 			else
 			{
-#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+			        ao2_cleanup(channel_tech.capabilities);
+			        channel_tech.capabilities = NULL;
+#elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
 				channel_tech.capabilities = ast_format_cap_destroy(channel_tech.capabilities);
 #endif
 				ast_log (LOG_ERROR, "Unable to register channel class %s\n", channel_tech.type);
@@ -1717,7 +1730,11 @@ static void public_state_fini(struct public_state * state)
 {
 	/* First, take us out of the channel loop */
 	ast_channel_unregister (&channel_tech);
-#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+        ao2_cleanup(channel_tech.capabilities);
+        channel_tech.capabilities = NULL;
+
+#elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
 	channel_tech.capabilities = ast_format_cap_destroy(channel_tech.capabilities);
 #endif
 
@@ -1766,9 +1783,15 @@ static int reload_module()
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, MODULE_DESCRIPTION,
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+		.support_level = AST_MODULE_SUPPORT_EXTENDED,
+#endif
 		.load = load_module,
 		.unload = unload_module,
 		.reload = reload_module,
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+		.load_pri = AST_MODPRI_CHANNEL_DRIVER,
+#endif
 	       );
 
 //AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY, MODULE_DESCRIPTION);
diff --git a/chan_dongle.h b/chan_dongle.h
index b3adab7..a94cfbb 100644
--- a/chan_dongle.h
+++ b/chan_dongle.h
@@ -38,9 +38,10 @@ INLINE_DECL const char * dev_state2str_msg(dev_state_t state)
 	return enum2str(state, states, ITEMS_OF(states));
 }
 
-#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+#if ASTERISK_VERSION_NUM >= 100000 && ASTERISK_VERSION_NUM < 130000 /* 10+..13- */
 /* Only linear is allowed */
 EXPORT_DECL struct ast_format chan_dongle_format;
+//EXPORT_DEF struct ast_format chan_dongle_format;
 EXPORT_DECL struct ast_format_cap * chan_dongle_format_cap;
 #endif
 
diff --git a/channel.c b/channel.c
index 73e4033..7c978e6 100644
--- a/channel.c
+++ b/channel.c
@@ -26,6 +26,10 @@
 #include <asterisk/timing.h>			/* ast_timer_fd() ast_timer_set_rate() ast_timer_ack() */
 
 #include "ast_compat.h"
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+#include <asterisk/stasis_channels.h>
+#include <asterisk/format_cache.h>
+#endif
 
 #include "channel.h"
 #include "chan_dongle.h"
@@ -96,23 +100,27 @@ EXPORT_DEF int channels_loop(struct pvt * pvt, const struct ast_channel * reques
 	/* FIXME: requestor may be just proxy/masquerade for real channel */
 	//	use ast_bridged_channel(chan) ?
 	//	use requestor->tech->get_base_channel() ?
-	struct cpvt *cpvt = ast_channel_tech_pvt(requestor);
-	if(requestor && ast_channel_tech(requestor) == &channel_tech && cpvt && cpvt->pvt == pvt)
-		return 1;
-	return 0;
+	return (requestor
+		&& ast_channel_tech(requestor) == &channel_tech
+		&& ast_channel_tech_pvt(requestor)
+		&& ((struct cpvt*) ast_channel_tech_pvt(requestor))->pvt == pvt)
+		? 1
+		: 0;
 }
 
-// TODO: simplify by move common code to functions
-/* TODO: add check when request 'holdother' what requestor is not on same device for 1.6 */
-#if ASTERISK_VERSION_NUM >= 110000 /* 11+ */
-static struct ast_channel * channel_request (attribute_unused const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
-#elif ASTERISK_VERSION_NUM >= 100000 /* 10+ */
-static struct ast_channel * channel_request (attribute_unused const char * type, struct ast_format_cap * cap, const struct ast_channel *requestor, void * data, int * cause)
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+static struct ast_channel * channel_request (attribute_unused const char * type, struct ast_format_cap * cap, const struct ast_assigned_ids * assignedids, const struct ast_channel * requestor, const char * data, int * cause)
+#elif ASTERISK_VERSION_NUM >= 110000 /* 11+ */
+static struct ast_channel * channel_request (attribute_unused const char * type, struct ast_format_cap * cap, const struct ast_channel * requestor, const char * data, int * cause)
+#elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
+static struct ast_channel * channel_request (attribute_unused const char * type, struct ast_format_cap * cap, const struct ast_channel * requestor, void * data, int * cause)
 #elif ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
+//   TODO: simplify by move common code to functions
 static struct ast_channel * channel_request (attribute_unused const char * type, format_t format, const struct ast_channel * requestor, void * data, int * cause)
-#else /* #if ASTERISK_VERSION_NUM < 10800 */
+#else /* 1.8- */
+/* TODO: add check when request 'holdother' what requestor is not on same device for 1.6 */
 static struct ast_channel * channel_request (attribute_unused const char * type, int format, void * data, int * cause)
-#endif /* #if ASTERISK_VERSION_NUM < 10800 */
+#endif
 {
 #if ASTERISK_VERSION_NUM >= 10800 && ASTERISK_VERSION_NUM < 100000 /* 1.8+ .. 10- */
 	format_t oldformat;
@@ -134,15 +142,20 @@ static struct ast_channel * channel_request (attribute_unused const char * type,
 		return NULL;
 	}
 
-#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+	if (ast_format_cap_iscompatible_format(cap, ast_format_slin) != AST_FORMAT_CMP_EQUAL)
+#elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
 	if (!ast_format_cap_iscompatible(cap, &chan_dongle_format))
 #else
-        oldformat = format;
-        format &= AST_FORMAT_SLINEAR;
-        if (!format)
+	oldformat = format;
+	format &= AST_FORMAT_SLINEAR;
+	if (!format)
 #endif
-        {
-#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+	{
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+		struct ast_str *codec_buf = ast_str_alloca(64);
+		ast_log (LOG_WARNING, "Asked to get a channel of unsupported format '%s'\n", ast_format_cap_get_names(cap, &codec_buf));
+#elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
 		char buf[255];
 		ast_log (LOG_WARNING, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple (buf, 255, cap));
 #elif ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
@@ -167,7 +180,11 @@ static struct ast_channel * channel_request (attribute_unused const char * type,
 #endif
 	if(pvt)
 	{
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+		channel = new_channel (pvt, AST_STATE_DOWN, NULL, pvt_get_pseudo_call_idx(pvt), CALL_DIR_OUTGOING, CALL_STATE_INIT, NULL, assignedids, requestor);
+#else
 		channel = new_channel (pvt, AST_STATE_DOWN, NULL, pvt_get_pseudo_call_idx(pvt), CALL_DIR_OUTGOING, CALL_STATE_INIT, NULL, requestor);
+#endif
 		ast_mutex_unlock (&pvt->lock);
 		if(!channel)
 		{
@@ -592,13 +609,13 @@ static void write_conference(struct pvt * pvt, const char * buffer, size_t lengt
 
 
 #if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
-#define subclass_integer       subclass.integer
+#define subclass_integer	subclass.integer
 #elif ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
-#define subclass_codec         subclass.codec
-#define subclass_integer       subclass.integer
+#define subclass_codec		subclass.codec
+#define subclass_integer	subclass.integer
 #else /* 1.8- */
-#define subclass_codec         subclass
-#define subclass_integer       subclass
+#define subclass_codec		subclass
+#define subclass_integer	subclass
 #endif
 
 #/* */
@@ -640,7 +657,9 @@ static struct ast_frame* channel_read (struct ast_channel* channel)
 		memset (&cpvt->a_read_frame, 0, sizeof (cpvt->a_read_frame));
 
 		cpvt->a_read_frame.frametype = AST_FRAME_VOICE;
-#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+		cpvt->a_read_frame.subclass.format = ao2_bump(ast_format_slin);
+#elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
 		ast_format_copy(&cpvt->a_read_frame.subclass.format, &chan_dongle_format);
 #else
 		cpvt->a_read_frame.subclass_codec = AST_FORMAT_SLINEAR;
@@ -758,7 +777,9 @@ static int channel_write (struct ast_channel* channel, struct ast_frame* f)
 	size_t count;
 	int gains[2];
 
-#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+	if (f->frametype != AST_FRAME_VOICE || ast_format_cmp(f->subclass.format, ast_format_slin) != AST_FORMAT_CMP_EQUAL)
+#elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
 	if (f->frametype != AST_FRAME_VOICE || f->subclass.format.id != AST_FORMAT_SLINEAR)
 #else /* 10- */
 	if (f->frametype != AST_FRAME_VOICE || f->subclass_codec != AST_FORMAT_SLINEAR)
@@ -793,13 +814,16 @@ static int channel_write (struct ast_channel* channel, struct ast_frame* f)
 
 	if(CPVT_TEST_FLAG(cpvt, CALL_FLAG_MULTIPARTY) && !CPVT_TEST_FLAG(cpvt, CALL_FLAG_BRIDGE_CHECK))
 	{
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+		RAII_VAR(struct ast_channel *, bridged, ast_channel_bridge_peer(channel), ast_channel_cleanup);
+#else
 		struct ast_channel* bridged = ast_bridged_channel(channel);
+#endif
 		struct cpvt *tmp_cpvt;
 
 		CPVT_SET_FLAGS(cpvt, CALL_FLAG_BRIDGE_CHECK);
 
-		tmp_cpvt = ast_channel_tech_pvt(bridged);
-		if(bridged && ast_channel_tech(bridged) == &channel_tech && tmp_cpvt && tmp_cpvt->pvt == pvt)
+		if (bridged && ast_channel_tech(bridged) == &channel_tech && (tmp_cpvt = ast_channel_tech_pvt(bridged)) && tmp_cpvt->pvt == pvt)
 		{
 			CPVT_SET_FLAGS(cpvt, CALL_FLAG_BRIDGE_LOOP);
 			CPVT_SET_FLAGS((struct cpvt*)ast_channel_tech_pvt(bridged), CALL_FLAG_BRIDGE_LOOP);
@@ -1004,6 +1028,7 @@ static int channel_indicate (struct ast_channel* channel, int condition, const v
 		case AST_CONTROL_PROCEEDING:
 		case AST_CONTROL_VIDUPDATE:
 		case AST_CONTROL_SRCUPDATE:
+		case AST_CONTROL_PVT_CAUSE_CODE://33
 			break;
 
 		case AST_CONTROL_HOLD:
@@ -1154,7 +1179,12 @@ static void set_channel_vars(struct pvt* pvt, struct ast_channel* channel)
 		{ "DONGLENUMBER", pvt->subscriber_number },
 	};
 
+#if ASTERISK_VERSION_NUM >= 110000 /* 11+  */
 	ast_channel_language_set(channel, CONF_SHARED(pvt, language));
+#else
+	//TODO uncomment and fix
+	//ast_string_field_set (channel, language, CONF_SHARED(pvt, language);
+#endif
 
 	for(idx = 0; idx < ITEMS_OF(dev_vars); ++idx)
 		pbx_builtin_setvar_helper (channel, dev_vars[idx].name, dev_vars[idx].value);
@@ -1162,16 +1192,24 @@ static void set_channel_vars(struct pvt* pvt, struct ast_channel* channel)
 }
 
 #/* NOTE: called from device and current levels with locked pvt */
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+EXPORT_DEF struct ast_channel* new_channel (struct pvt* pvt, int ast_state, const char* cid_num, int call_idx, unsigned dir, call_state_t state, const char * dnid, const struct ast_assigned_ids *assignedids, attribute_unused const struct ast_channel * requestor)
+#else
 EXPORT_DEF struct ast_channel* new_channel (struct pvt* pvt, int ast_state, const char* cid_num, int call_idx, unsigned dir, call_state_t state, const char * dnid, attribute_unused const struct ast_channel * requestor)
+#endif
 {
+//        struct ast_channel * channel = new_channel (pvt, AST_STATE_RING, number, call_idx, CALL_DIR_INCOMING, state, pvt->has_subscriber_number ? pvt->subscriber_number : CONF_SHARED(pvt, exten), $
+
 	struct ast_channel* channel;
 	struct cpvt * cpvt;
 
 	cpvt = cpvt_alloc(pvt, call_idx, dir, state);
 	if (cpvt)
 	{
-#if ASTERISK_VERSION_NUM >= 10800
-		channel = ast_channel_alloc (1, ast_state, cid_num, PVT_ID(pvt), NULL, dnid, CONF_SHARED(pvt, context), requestor ? ast_channel_linkedid(requestor) : NULL, 0, "%s/%s-%02u%08lx", channel_tech.type, PVT_ID(pvt), call_idx, pvt->channel_instanse);
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+                channel = ast_channel_alloc (1, ast_state, cid_num, PVT_ID(pvt), NULL, dnid, CONF_SHARED(pvt, context), assignedids, requestor, 0, "%s/%s-%02u%08lx", channel_tech.type, PVT_ID(pvt), call_idx, pvt->channel_instanse);
+#elif ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
+		channel = ast_channel_alloc (1, ast_state, cid_num, PVT_ID(pvt), NULL, dnid, CONF_SHARED(pvt, context), requestor ? ast_channel_linkedid(requestor): NULL, 0, "%s/%s-%02u%08lx", channel_tech.type, PVT_ID(pvt), call_idx, pvt->channel_instanse);
 #else
 		channel = ast_channel_alloc (1, ast_state, cid_num, PVT_ID(pvt), NULL, dnid, CONF_SHARED(pvt, context), 0, "%s/%s-%02u%08lx", channel_tech.type, PVT_ID(pvt), call_idx, pvt->channel_instanse);
 #endif
@@ -1183,8 +1221,11 @@ EXPORT_DEF struct ast_channel* new_channel (struct pvt* pvt, int ast_state, cons
 			ast_channel_tech_pvt_set(channel, cpvt);
 			ast_channel_tech_set(channel, &channel_tech);
 
-
-#if ASTERISK_VERSION_NUM >= 110000 /* 11+ */
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+			ast_format_cap_append(ast_channel_nativeformats(channel), ast_format_slin, 0);
+			ast_channel_set_writeformat(channel, ast_format_slin);
+			ast_channel_set_readformat(channel, ast_format_slin);
+#elif ASTERISK_VERSION_NUM >= 110000 /* 11+ */
 			ast_format_set(ast_channel_readformat(channel), AST_FORMAT_SLINEAR, 0);
 			ast_format_set(ast_channel_writeformat(channel), AST_FORMAT_SLINEAR, 0);
 			ast_format_cap_set(ast_channel_nativeformats(channel), ast_channel_writeformat(channel));
@@ -1285,11 +1326,13 @@ EXPORT_DEF void start_local_channel (struct pvt* pvt, const char* exten, const c
 
 	snprintf (channel_name, sizeof (channel_name), "%s@%s", exten, CONF_SHARED(pvt, context));
 
-#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+	channel = ast_request ("Local", channel_tech.capabilities, NULL, NULL, channel_name, &cause);
+#elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
 	channel = ast_request ("Local", chan_dongle_format_cap, NULL, channel_name, &cause);
 #elif ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
 	channel = ast_request ("Local", AST_FORMAT_AUDIO_MASK, NULL, channel_name, &cause);
-#else
+#else /* 1.8- */
 	channel = ast_request ("Local", AST_FORMAT_AUDIO_MASK, channel_name, &cause);
 #endif
 	if (channel)
@@ -1374,7 +1417,7 @@ static int channel_func_read(struct ast_channel* channel, attribute_unused const
 static int channel_func_write(struct ast_channel* channel, const char* function, char* data, const char* value)
 {
 	struct cpvt* cpvt = ast_channel_tech_pvt(channel);
-	struct pvt* pvt;
+	struct pvt* pvt = cpvt->pvt;
 	call_state_t newstate, oldstate;
 	int ret = 0;
 
@@ -1383,7 +1426,6 @@ static int channel_func_write(struct ast_channel* channel, const char* function,
 		ast_log (LOG_WARNING, "call on unreferenced %s\n", ast_channel_name(channel));
 		return -1;
 	}
-	pvt = cpvt->pvt;
 
 	if (!strcasecmp(data, "callstate"))
 	{
@@ -1455,7 +1497,7 @@ EXPORT_DEF struct ast_channel_tech channel_tech =
 	.type			= "Dongle",
 	.description		= MODULE_DESCRIPTION,
 #if ASTERISK_VERSION_NUM < 100000 /* 10- */
-	.capabilities           = AST_FORMAT_SLINEAR,
+	.capabilities		= AST_FORMAT_SLINEAR,
 #endif
 	.requester		= channel_request,
 	.call			= channel_call,
diff --git a/channel.h b/channel.h
index e62bc9d..702e3f2 100644
--- a/channel.h
+++ b/channel.h
@@ -21,7 +21,11 @@ struct cpvt;
 
 EXPORT_DECL struct ast_channel_tech channel_tech;
 
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+EXPORT_DECL struct ast_channel* new_channel (struct pvt * pvt, int ast_state, const char * cid_num, int call_idx, unsigned dir, unsigned state, const char * exten, const struct ast_assigned_ids *assignedids, const struct ast_channel * requestor);
+#else
 EXPORT_DECL struct ast_channel* new_channel (struct pvt * pvt, int ast_state, const char * cid_num, int call_idx, unsigned dir, unsigned state, const char * exten, const struct ast_channel * requestor);
+#endif
 EXPORT_DECL int queue_control_channel (struct cpvt * cpvt, enum ast_control_frame_type control);
 EXPORT_DECL int queue_hangup (struct ast_channel * channel, int hangupcause);
 EXPORT_DECL void start_local_channel (struct pvt * pvt, const char * exten, const char * number, channel_var_t * vars);
diff --git a/manager.c b/manager.c
index 4f9e962..0f9a0ca 100644
--- a/manager.c
+++ b/manager.c
@@ -731,9 +731,16 @@ static const struct dongle_manager
 EXPORT_DEF void manager_register()
 {
 	unsigned i;
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+	struct ast_module* module = self_module();
+#endif
+
 	for(i = 0; i < ITEMS_OF(dcm); i++)
 	{
-#if ASTERISK_VERSION_NUM >= 110000
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+		ast_manager_register2 (dcm[i].name, dcm[i].authority, dcm[i].func,
+			module, dcm[i].brief, dcm[i].desc);
+#elif ASTERISK_VERSION_NUM >= 110000 /* 11+ */
 		ast_manager_register2 (dcm[i].name, dcm[i].authority, dcm[i].func, NULL, dcm[i].brief, dcm[i].desc);
 #else
 		ast_manager_register2 (dcm[i].name, dcm[i].authority, dcm[i].func, dcm[i].brief, dcm[i].desc);
diff --git a/pdu.c b/pdu.c
index 5f87db3..e0bdab7 100644
--- a/pdu.c
+++ b/pdu.c
@@ -463,7 +463,7 @@ static int pdu_parse_number(char ** pdu, size_t * pdu_length, unsigned digits, i
 				*number++ = digit;
 
 				digit = pdu_code2digit(pdu[0][0]);
-				if(digit < 0 || (digit == 0 && (syms != 2 || (digits & 0x1) == 0)))
+				if((signed char)digit < 0 || (digit == 0 && (syms != 2 || (digits & 0x1) == 0)))
 					return -1;
 
 				*number++ = digit;

From 897b27c273d302c2217319c5ff5de44024682846 Mon Sep 17 00:00:00 2001
From: Walter Doekes <walter+github@wjd.nu>
Date: Sat, 5 Sep 2015 23:08:09 +0200
Subject: [PATCH 07/15] Translate NUL to @ in incoming SMS.

Author: mio
Source: https://github.com/bg111/asterisk-chan-dongle/issues/153

Not using full 3GPP version from https://code.google.com/p/
  asterisk-chan-dongle/issues/detail?id=140 because of the issues
described there.

This should simply fix that you don't get a truncated SMS because of an
@ sign.
---
 char_conv.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/char_conv.c b/char_conv.c
index 3167f30..2a4be70 100644
--- a/char_conv.c
+++ b/char_conv.c
@@ -235,11 +235,20 @@ static ssize_t hexstr_7bit_to_char (const char* in, size_t in_length, char* out,
 		c = (c >> 1) | b;
 		b = ((unsigned char) hexval) >> (8 - s);
 
+		if (c == 0 && i + 1 < in_length) {
+			/* @ is encoded as NUL */
+			c = '@';
+		}
+
 		out[x] = c;
 		x++; s++;
 
 		if (s == 8)
 		{
+			if (b == 0 && i + 1 < in_length) {
+				/* @ is encoded as NUL */
+				b = '@';
+			}
 			out[x] = b;
 			s = 1; b = 0;
 			x++;

From cd03d3a8fc000782eb97293ed874c31973d7b64f Mon Sep 17 00:00:00 2001
From: Walter Doekes <walter+github@wjd.nu>
Date: Sun, 6 Sep 2015 11:25:25 +0200
Subject: [PATCH 08/15] Fix so Asterisk 1.8 compilation works again.

---
 channel.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/channel.c b/channel.c
index 7c978e6..1875748 100644
--- a/channel.c
+++ b/channel.c
@@ -1028,7 +1028,9 @@ static int channel_indicate (struct ast_channel* channel, int condition, const v
 		case AST_CONTROL_PROCEEDING:
 		case AST_CONTROL_VIDUPDATE:
 		case AST_CONTROL_SRCUPDATE:
-		case AST_CONTROL_PVT_CAUSE_CODE://33
+#if ASTERISK_VERSION_NUM >= 110000 /* 11+ */
+		case AST_CONTROL_PVT_CAUSE_CODE:
+#endif /* ^11+ */
 			break;
 
 		case AST_CONTROL_HOLD:

From 7eb9b856e3824fc5fb44158dd03b74fdeef637fe Mon Sep 17 00:00:00 2001
From: Walter Doekes <walter+github@wjd.nu>
Date: Sun, 6 Sep 2015 11:25:48 +0200
Subject: [PATCH 09/15] Spaces cleanup. Asterisk version number cleanup.

---
 app.c         |  20 +++---
 ast_compat.h  |   8 +--
 at_command.c  |  26 +++----
 at_parse.c    |  35 +++++-----
 at_queue.c    |  20 +++---
 at_read.c     |   2 +-
 at_response.c | 175 ++++++++++++++++++++++++------------------------
 chan_dongle.c | 120 +++++++++++++++------------------
 chan_dongle.h |  10 +--
 channel.c     | 201 ++++++++++++++++++++++++++++++++-----------------------
 channel.h     |  17 +++--
 char_conv.c   |   4 +-
 cli.c         |  31 ++++-----
 cpvt.c        |   2 +-
 dc_config.c   |   4 +-
 helpers.c     |   6 +-
 manager.c     |  76 +++++++++++----------
 mixbuffer.c   |   2 +-
 pdiscovery.c  |  39 +++++------
 pdu.c         | 212 +++++++++++++++++++++++++++++-----------------------------
 ringbuffer.c  |  16 ++---
 ringbuffer.h  |   6 +-
 test/parse.c  |  69 +++++++------------
 23 files changed, 553 insertions(+), 548 deletions(-)

diff --git a/app.c b/app.c
index a46fc8d..6ea5e93 100644
--- a/app.c
+++ b/app.c
@@ -3,12 +3,12 @@
 #endif /* HAVE_CONFIG_H */
 
 #ifdef BUILD_APPLICATIONS
-/* 
+/*
    Copyright (C) 2009 - 2010
-   
+
    Artem Makhutov <artem@makhutov.org>
    http://www.makhutov.org
-   
+
    Dmitry Vagin <dmitry2004@yandex.ru>
 
    bg <bg_one@mail.ru>
@@ -124,7 +124,7 @@ static const struct dongle_application
 	int		(*func)(struct ast_channel* channel, const char* data);
 	const char*	synopsis;
 	const char*	desc;
-} dca[] = 
+} dca[] =
 {
 	{
 		"DongleStatus",
@@ -138,7 +138,7 @@ static const struct dongle_application
 	{
 		"DongleSendSMS",
 		app_send_sms_exec,
-		"DongleSendSMS(Device,Dest,Message,Validity,Report)", 
+		"DongleSendSMS(Device,Dest,Message,Validity,Report)",
 		"DongleSendSMS(Device,Dest,Message,Validity,Report)\n"
 		"  Device   - Id of device from dongle.conf\n"
 		"  Dest     - destination\n"
@@ -148,11 +148,11 @@ static const struct dongle_application
 	}
 };
 
-#if ASTERISK_VERSION_NUM >= 10800
-typedef int		(*app_func_t)(struct ast_channel* channel, const char * data);
-#else
-typedef int		(*app_func_t)(struct ast_channel* channel, void * data);
-#endif
+#if ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
+typedef int (*app_func_t)(struct ast_channel *channel, const char *data);
+#else /* 1.8- */
+typedef int (*app_func_t)(struct ast_channel *channel, void *data);
+#endif /* ^1.8- */
 
 #/* */
 EXPORT_DEF void app_register()
diff --git a/ast_compat.h b/ast_compat.h
index c22b75e..1ad407a 100644
--- a/ast_compat.h
+++ b/ast_compat.h
@@ -10,7 +10,7 @@
 #include <asterisk/channel.h>
 
 /* Asterisk 11+ channel opaqification */
-#if ASTERISK_VERSION_NUM < 110000
+#if ASTERISK_VERSION_NUM < 110000 /* 11- */
 
 /* channel->name */
 static inline const char *ast_channel_name(const struct ast_channel *chan) { return chan->name; }
@@ -44,13 +44,13 @@ static inline const char *ast_channel_linkedid(const struct ast_channel *chan) {
 /* channel->hangupcause */
 static inline void ast_channel_hangupcause_set(struct ast_channel *chan, int value) { chan->hangupcause = value; }
 
-#if ASTERISK_VERSION_NUM >= 100000
+#if ASTERISK_VERSION_NUM >= 100000 /* 10+ */
 /* channel->*format* */
 static inline struct ast_format_cap *ast_channel_nativeformats(const struct ast_channel *chan) { return chan->nativeformats; }
 static inline struct ast_format ast_channel_readformat(const struct ast_channel *chan) { return chan->readformat; }
 static inline struct ast_format ast_channel_writeformat(const struct ast_channel *chan) { return chan->writeformat; }
-#endif
+#endif /* ^10+ */
 
-#endif
+#endif /* ^11- */
 
 #endif /* CHAN_DONGLE_AST_COMPAT_H_INCLUDED */
diff --git a/at_command.c b/at_command.c
index 8c2a5a7..8ed6c84 100644
--- a/at_command.c
+++ b/at_command.c
@@ -1,9 +1,9 @@
-/* 
+/*
    Copyright (C) 2009 - 2010
-   
+
    Artem Makhutov <artem@makhutov.org>
    http://www.makhutov.org
-   
+
    Dmitry Vagin <dmitry2004@yandex.ru>
 
    bg <bg_one@mail.ru>
@@ -46,7 +46,7 @@ static const char cmd_ddsetex2[] = "AT^DDSETEX=2\r";
 static int at_fill_generic_cmd_va (at_queue_cmd_t * cmd, const char * format, va_list ap)
 {
 	char buf[4096];
-	
+
 	cmd->length = vsnprintf (buf, sizeof(buf)-1, format, ap);
 
 	buf[cmd->length] = 0;
@@ -255,7 +255,7 @@ EXPORT_DEF int at_enque_pdu(struct cpvt * cpvt, const char * pdu, attribute_unus
 	size_t pdulen = length;
 
 	int scalen = pdu_parse_sca(&ptr, &pdulen);
-	
+
 	if(scalen < 2 || length % 2 != 0)
 	{
 		return -EINVAL;
@@ -263,7 +263,7 @@ EXPORT_DEF int at_enque_pdu(struct cpvt * cpvt, const char * pdu, attribute_unus
 
 	at_cmd[1].data = ast_malloc(length + 2);
 	if(!at_cmd[1].data)
-	{		
+	{
 		return -ENOMEM;
 	}
 
@@ -272,15 +272,15 @@ EXPORT_DEF int at_enque_pdu(struct cpvt * cpvt, const char * pdu, attribute_unus
 	memcpy(at_cmd[1].data, pdu, length);
 	at_cmd[1].data[length] = 0x1A;
 	at_cmd[1].data[length+1] = 0x0;
-		
+
 	at_cmd[0].length = snprintf(buf, sizeof(buf), "AT+CMGS=%d\r", (int)(pdulen / 2));
 	at_cmd[0].data = ast_strdup(buf);
 	if(!at_cmd[0].data)
 	{
 		ast_free(at_cmd[1].data);
-		return -ENOMEM;		
+		return -ENOMEM;
 	}
-			
+
 /*		ast_debug (5, "[%s] PDU Head '%s'\n", PVT_ID(pvt), buf);
 		ast_debug (5, "[%s] PDU Body '%s'\n", PVT_ID(pvt), at_cmd[1].data);
 */
@@ -300,7 +300,7 @@ EXPORT_DEF int at_enque_sms (struct cpvt* cpvt, const char* destination, const c
 	char buf[1024] = "AT+CMGS=\"";
 	char pdu_buf[2048];
 	pvt_t* pvt = cpvt->pvt;
-	
+
 	at_queue_cmd_t at_cmd[] = {
 		{ CMD_AT_CMGS,    RES_SMS_PROMPT, ATQ_CMD_FLAG_DEFAULT, { ATQ_CMD_TIMEOUT_2S, 0}  , NULL, 0 },
 		{ CMD_AT_SMSTEXT, RES_OK,         ATQ_CMD_FLAG_DEFAULT, { ATQ_CMD_TIMEOUT_40S, 0} , NULL, 0 }
@@ -655,7 +655,7 @@ EXPORT_DEF int at_enque_activate (struct cpvt* cpvt)
 
 	if (cpvt->state != CALL_STATE_ONHOLD && cpvt->state != CALL_STATE_WAITING)
 	{
-		ast_log (LOG_ERROR, "[%s] Imposible activate call idx %d from state '%s'\n", 
+		ast_log (LOG_ERROR, "[%s] Imposible activate call idx %d from state '%s'\n",
 				PVT_ID(cpvt->pvt), cpvt->call_idx, call_state2str(cpvt->state));
 		return -1;
 	}
@@ -811,11 +811,11 @@ EXPORT_DEF int at_enque_hangup (struct cpvt* cpvt, int call_idx)
 		not found yes
 */
 /*
-	static const struct 
+	static const struct
 	{
 		at_cmd_t	cmd;
 		const char	*data;
-	} commands[] = 
+	} commands[] =
 	{
 		{ CMD_AT_CHUP, "AT+CHUP\r" },
 		{ CMD_AT_CHLD_1x, "AT+CHLD=1%d\r" }
diff --git a/at_parse.c b/at_parse.c
index 27ef6d7..85172cb 100644
--- a/at_parse.c
+++ b/at_parse.c
@@ -1,9 +1,9 @@
-/* 
+/*
    Copyright (C) 2009 - 2010
-   
+
    Artem Makhutov <artem@makhutov.org>
    http://www.makhutov.org
-   
+
    Dmitry Vagin <dmitry2004@yandex.ru>
 
    bg <bg_one@mail.ru>
@@ -27,7 +27,7 @@
 static unsigned mark_line(char * line, const char * delimiters, char * pointers[])
 {
 	unsigned found = 0;
-	
+
 	for(; line[0] && delimiters[found]; line++)
 	{
 		if(line[0] == delimiters[found])
@@ -89,7 +89,7 @@ EXPORT_DEF char* at_parse_cops (char* str)
 	 * parse COPS response in the following format:
 	 * +COPS: <mode>[,<format>,<oper>,<?>]
 	 *
-	 * example 
+	 * example
 	 *  +COPS: 0,0,"TELE2",0
 	 */
 
@@ -265,7 +265,7 @@ EXPORT_DEF int at_parse_cmti (const char* str)
 
 	/*
 	 * parse cmti info in the following format:
-	 * +CMTI: <mem>,<index> 
+	 * +CMTI: <mem>,<index>
 	 */
 
 	return sscanf (str, "+CMTI: %*[^,],%u", &index) == 1 ? index : -1;
@@ -288,7 +288,7 @@ static const char * parse_cmgr_text(char ** str, size_t len, char * oa, size_t o
 	char delimiters[] = ",,,\n";
 	char * marks[STRLEN(delimiters)];
 	size_t length;
-	
+
 	unsigned count = mark_line(*str, delimiters, marks);
 	if(count == ITEMS_OF(marks))
 	{
@@ -420,7 +420,7 @@ EXPORT_DEF int at_parse_cusd (char* str, int * type, char** cusd, int * dcs)
 	/*
 	 * parse cusd message in the following format:
 	 * +CUSD: <m>,[<str>,<dcs>]
-	 * 
+	 *
 	 * examples
 	 *   +CUSD: 5
 	 *   +CUSD: 0,"100,00 EURO, valid till 01.01.2010, you are using tariff "Mega Tariff". More informations *111#.",15
@@ -597,17 +597,12 @@ EXPORT_DEF int at_parse_clcc(char* str, unsigned * call_idx, unsigned * dir, uns
 
 	if(mark_line(str, delimiters, marks) == ITEMS_OF(marks))
 	{
-		if( sscanf(marks[0] + 1, "%u", call_idx) == 1
-			&&
-		    sscanf(marks[1] + 1, "%u", dir) == 1
-			&&
-		    sscanf(marks[2] + 1, "%u", state) == 1
-			&&
-		    sscanf(marks[3] + 1, "%u", mode) == 1
-			&&
-		    sscanf(marks[4] + 1, "%u", mpty) == 1
-			&&
-		    sscanf(marks[6] + 1, "%u", toa) == 1) 
+		if(sscanf(marks[0] + 1, "%u", call_idx) == 1
+			&& sscanf(marks[1] + 1, "%u", dir) == 1
+			&& sscanf(marks[2] + 1, "%u", state) == 1
+			&& sscanf(marks[3] + 1, "%u", mode) == 1
+			&& sscanf(marks[4] + 1, "%u", mpty) == 1
+			&& sscanf(marks[6] + 1, "%u", toa) == 1)
 		{
 			marks[5]++;
 			if(marks[5][0] == '"')
@@ -627,7 +622,7 @@ EXPORT_DEF int at_parse_clcc(char* str, unsigned * call_idx, unsigned * dir, uns
 #/* */
 EXPORT_DEF int at_parse_ccwa(char* str, unsigned * class)
 {
-	/* 
+	/*
 	 * CCWA may be in form:
 	 *	in response of AT+CCWA=?
 	 *		+CCWA: (0,1)
diff --git a/at_queue.c b/at_queue.c
index def4777..dc480a7 100644
--- a/at_queue.c
+++ b/at_queue.c
@@ -1,4 +1,4 @@
-/* 
+/*
    Copyright (C) 2009 - 2010
 
    Artem Makhutov <artem@makhutov.org>
@@ -28,7 +28,7 @@ static void at_queue_free_data(at_queue_cmd_t * cmd)
 {
 	if(cmd->data)
 	{
-		if((cmd->flags & ATQ_CMD_FLAG_STATIC) == 0) 
+		if((cmd->flags & ATQ_CMD_FLAG_STATIC) == 0)
 		{
 			ast_free (cmd->data);
 			cmd->data = NULL;
@@ -67,8 +67,8 @@ static void at_queue_remove (struct pvt * pvt)
 	{
 		PVT_STATE(pvt, at_tasks)--;
 		PVT_STATE(pvt, at_cmds) -= task->cmdsno - task->cindex;
-		ast_debug (4, "[%s] remove task with %u command(s) begin with '%s' expected response '%s' from queue\n", 
-				PVT_ID(pvt), task->cmdsno, at_cmd2str (task->cmds[0].cmd), 
+		ast_debug (4, "[%s] remove task with %u command(s) begin with '%s' expected response '%s' from queue\n",
+				PVT_ID(pvt), task->cmdsno, at_cmd2str (task->cmds[0].cmd),
 				at_res2str (task->cmds[0].res));
 
 		at_queue_free(task);
@@ -124,8 +124,8 @@ static at_queue_task_t * at_queue_add (struct cpvt * cpvt, const at_queue_cmd_t
 			PVT_STAT(pvt, at_tasks) ++;
 			PVT_STAT(pvt, at_cmds) += cmdsno;
 
-			ast_debug (4, "[%s] insert task with %u commands begin with '%s' expected response '%s' %s of queue\n", 
-					PVT_ID(pvt), e->cmdsno, at_cmd2str (e->cmds[0].cmd), 
+			ast_debug (4, "[%s] insert task with %u commands begin with '%s' expected response '%s' %s of queue\n",
+					PVT_ID(pvt), e->cmdsno, at_cmd2str (e->cmds[0].cmd),
 					at_res2str (e->cmds[0].res), prio ? "after head" : "at tail");
 		}
 	}
@@ -218,9 +218,9 @@ EXPORT_DEF void at_queue_remove_cmd (struct pvt* pvt, at_res_t res)
 
 		task->cindex++;
 		PVT_STATE(pvt, at_cmds)--;
-		ast_debug (4, "[%s] remove command '%s' expected response '%s' real '%s' cmd %u/%u flags 0x%02x from queue\n", 
-				PVT_ID(pvt), at_cmd2str (task->cmds[index].cmd), 
-				at_res2str (task->cmds[index].res), at_res2str (res), 
+		ast_debug (4, "[%s] remove command '%s' expected response '%s' real '%s' cmd %u/%u flags 0x%02x from queue\n",
+				PVT_ID(pvt), at_cmd2str (task->cmds[index].cmd),
+				at_res2str (task->cmds[index].res), at_res2str (res),
 				task->cindex, task->cmdsno, task->cmds[index].flags);
 
 		if((task->cindex >= task->cmdsno) || (task->cmds[index].res != res && (task->cmds[index].flags & ATQ_CMD_FLAG_IGNORE) == 0))
@@ -245,7 +245,7 @@ EXPORT_DEF int at_queue_run (struct pvt * pvt)
 	{
 		if(cmd->length > 0)
 		{
-			ast_debug (4, "[%s] write command '%s' expected response '%s' length %u\n", 
+			ast_debug (4, "[%s] write command '%s' expected response '%s' length %u\n",
 					PVT_ID(pvt), at_cmd2str (cmd->cmd), at_res2str (cmd->res), cmd->length);
 
 			fail = at_write(pvt, cmd->data, cmd->length);
diff --git a/at_read.c b/at_read.c
index 43e2f88..5bf7d74 100644
--- a/at_read.c
+++ b/at_read.c
@@ -79,7 +79,7 @@ EXPORT_DEF ssize_t at_read (int fd, const char * dev, struct ringbuffer* rb)
 		{
 			rb_write_upd (rb, n);
 
-			ast_debug (5, "[%s] receive %zu byte, used %zu, free %zu, read %zu, write %zu\n", 
+			ast_debug (5, "[%s] receive %zu byte, used %zu, free %zu, read %zu, write %zu\n",
 				dev, n, rb_used (rb), rb_free (rb), rb->read, rb->write);
 
 			iovcnt = rb_read_all_iov (rb, iov);
diff --git a/at_response.c b/at_response.c
index e8a35b6..83e800a 100644
--- a/at_response.c
+++ b/at_response.c
@@ -1,9 +1,9 @@
-/* 
+/*
    Copyright (C) 2009 - 2010
-   
+
    Artem Makhutov <artem@makhutov.org>
    http://www.makhutov.org
-   
+
    Dmitry Vagin <dmitry2004@yandex.ru>
 
    bg <bg_one@mail.ru>
@@ -215,7 +215,7 @@ static int at_response_ok (struct pvt* pvt, at_res_t res)
 
 			case CMD_AT_A:
 			case CMD_AT_CHLD_2x:
-/* not work, ^CONN: appear before OK for CHLD_ANSWER 
+/* not work, ^CONN: appear before OK for CHLD_ANSWER
 				task->cpvt->answered = 1;
 				task->cpvt->needhangup = 1;
 */
@@ -325,7 +325,7 @@ static int at_response_error (struct pvt* pvt, at_res_t res)
 	{
 		switch (ecmd->cmd)
 		{
-        		/* critical errors */
+			/* critical errors */
 			case CMD_AT:
 			case CMD_AT_Z:
 			case CMD_AT_E:
@@ -841,10 +841,16 @@ static int start_pbx(struct pvt* pvt, const char * number, int call_idx, call_st
 
 	/* TODO: pass also Subscriber number or other DID info for exten  */
 #if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
-	struct ast_channel * channel = new_channel (pvt, AST_STATE_RING, number, call_idx, CALL_DIR_INCOMING, state, pvt->has_subscriber_number ? pvt->subscriber_number : CONF_SHARED(pvt, exten), NULL, NULL);
-#else
-	struct ast_channel * channel = new_channel (pvt, AST_STATE_RING, number, call_idx, CALL_DIR_INCOMING, state, pvt->has_subscriber_number ? pvt->subscriber_number : CONF_SHARED(pvt, exten), NULL);
-#endif
+	struct ast_channel * channel = new_channel(
+			pvt, AST_STATE_RING, number, call_idx, CALL_DIR_INCOMING, state,
+			pvt->has_subscriber_number ? pvt->subscriber_number : CONF_SHARED(pvt, exten),
+			NULL, NULL);
+#else /* 13- */
+	struct ast_channel * channel = new_channel(
+			pvt, AST_STATE_RING, number, call_idx, CALL_DIR_INCOMING, state,
+			pvt->has_subscriber_number ? pvt->subscriber_number : CONF_SHARED(pvt, exten),
+			NULL);
+#endif /* ^13- */
 
 	if (!channel)
 	{
@@ -865,7 +871,7 @@ static int start_pbx(struct pvt* pvt, const char * number, int call_idx, call_st
 	// ast_pbx_start() usually failed if asterisk.conf minmemfree set too low, try drop buffer cache sync && echo 3 > /proc/sys/vm/drop_caches
 #if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
 	ast_channel_unlock(channel);
-#endif
+#endif /* ^13+ */
 	if (ast_pbx_start (channel))
 	{
 		ast_channel_tech_pvt_set(channel, NULL);
@@ -1050,7 +1056,7 @@ static int at_response_ccwa(struct pvt* pvt, char* str)
 	int status, n;
 	unsigned class;
 
-	/* 
+	/*
 	 * CCWA may be in form:
 	 *	in response of AT+CCWA=?
 	 *		+CCWA: (0,1)
@@ -1161,7 +1167,9 @@ static int at_response_cmti (struct pvt* pvt, const char* str)
 				return -1;
 			}
 			else
-			    pvt->incoming_sms = 1;
+			{
+				pvt->incoming_sms = 1;
+			}
 		}
 
 		return 0;
@@ -1203,82 +1211,82 @@ static int at_response_cmgr (struct pvt* pvt, const char * str, size_t len)
 	manager_event_message("DongleNewCMGR", PVT_ID(pvt), str);
 	if (ecmd)
 	{
-	    if (ecmd->res == RES_CMGR || ecmd->cmd == CMD_USER)
-	    {
-		at_queue_handle_result (pvt, RES_CMGR);
-		pvt->incoming_sms = 0;
-		pvt_try_restate(pvt);
-
-		cmgr = err_pos = ast_strdupa (str);
-		err = at_parse_cmgr (&err_pos, len, oa, sizeof(oa), &oa_enc, &msg, &msg_enc); // YYY
-		if (err == (void*)0x1) /* HACK! */
+		if (ecmd->res == RES_CMGR || ecmd->cmd == CMD_USER)
 		{
-			char buf[64];
-			int res = (int)(long)msg; /* HACK */
-			snprintf(buf, 64, "Delivered\r\nForeignID: %d", res);
-			manager_event_sent_notify(PVT_ID(pvt), "SMS", 0x0 /* task is popped */, buf);
-			return 0;
-		}
-		else if (err)
-		{
-			ast_log (LOG_WARNING, "[%s] Error parsing incoming message '%s' at possition %d: %s\n", PVT_ID(pvt), str, (int)(err_pos - cmgr), err);
-			return 0;
-		}
+			at_queue_handle_result (pvt, RES_CMGR);
+			pvt->incoming_sms = 0;
+			pvt_try_restate(pvt);
 
-		ast_debug (1, "[%s] Successfully read SMS message\n", PVT_ID(pvt));
+			cmgr = err_pos = ast_strdupa (str);
+			err = at_parse_cmgr (&err_pos, len, oa, sizeof(oa), &oa_enc, &msg, &msg_enc); // YYY
+			if (err == (void*)0x1) /* HACK! */
+			{
+				char buf[64];
+				int res = (int)(long)msg; /* HACK */
+				snprintf(buf, 64, "Delivered\r\nForeignID: %d", res);
+				manager_event_sent_notify(PVT_ID(pvt), "SMS", 0x0 /* task is popped */, buf);
+				return 0;
+			}
+			else if (err)
+			{
+				ast_log (LOG_WARNING, "[%s] Error parsing incoming message '%s' at possition %d: %s\n", PVT_ID(pvt), str, (int)(err_pos - cmgr), err);
+				return 0;
+			}
 
-		/* last chance to define encodings */
-		if (oa_enc == STR_ENCODING_UNKNOWN)
-			oa_enc = pvt->use_ucs2_encoding ? STR_ENCODING_UCS2_HEX : STR_ENCODING_7BIT;
+			ast_debug (1, "[%s] Successfully read SMS message\n", PVT_ID(pvt));
 
-		if (msg_enc == STR_ENCODING_UNKNOWN)
-			msg_enc = pvt->use_ucs2_encoding ? STR_ENCODING_UCS2_HEX : STR_ENCODING_7BIT;
+			/* last chance to define encodings */
+			if (oa_enc == STR_ENCODING_UNKNOWN)
+				oa_enc = pvt->use_ucs2_encoding ? STR_ENCODING_UCS2_HEX : STR_ENCODING_7BIT;
 
-		/* decode number and message */
-		res = str_recode (RECODE_DECODE, oa_enc, oa, strlen(oa), from_number_utf8_str, sizeof (from_number_utf8_str));
-		if (res < 0)
-		{
-			ast_log (LOG_ERROR, "[%s] Error decode SMS originator address: '%s', message is '%s'\n", PVT_ID(pvt), oa, str);
-			number = oa;
-			return 0;
-		}
-		else
-			number = from_number_utf8_str;
+			if (msg_enc == STR_ENCODING_UNKNOWN)
+				msg_enc = pvt->use_ucs2_encoding ? STR_ENCODING_UCS2_HEX : STR_ENCODING_7BIT;
 
-		msg_len = strlen(msg);
-		res = str_recode (RECODE_DECODE, msg_enc, msg, msg_len, sms_utf8_str, sizeof (sms_utf8_str));
-		if (res < 0)
-		{
-			ast_log (LOG_ERROR, "[%s] Error decode SMS text '%s' from encoding %d, message is '%s'\n", PVT_ID(pvt), msg, msg_enc, str);
-			return 0;
-		}
-		else
-		{
-			msg = sms_utf8_str;
-			msg_len = res;
-		}
+			/* decode number and message */
+			res = str_recode (RECODE_DECODE, oa_enc, oa, strlen(oa), from_number_utf8_str, sizeof (from_number_utf8_str));
+			if (res < 0)
+			{
+				ast_log (LOG_ERROR, "[%s] Error decode SMS originator address: '%s', message is '%s'\n", PVT_ID(pvt), oa, str);
+				number = oa;
+				return 0;
+			}
+			else
+				number = from_number_utf8_str;
+
+			msg_len = strlen(msg);
+			res = str_recode (RECODE_DECODE, msg_enc, msg, msg_len, sms_utf8_str, sizeof (sms_utf8_str));
+			if (res < 0)
+			{
+				ast_log (LOG_ERROR, "[%s] Error decode SMS text '%s' from encoding %d, message is '%s'\n", PVT_ID(pvt), msg, msg_enc, str);
+				return 0;
+			}
+			else
+			{
+				msg = sms_utf8_str;
+				msg_len = res;
+			}
 
-		ast_verb (1, "[%s] Got SMS from %s: '%s'\n", PVT_ID(pvt), number, msg);
-		ast_base64encode (text_base64, (unsigned char*)msg, msg_len, sizeof(text_base64));
+			ast_verb (1, "[%s] Got SMS from %s: '%s'\n", PVT_ID(pvt), number, msg);
+			ast_base64encode (text_base64, (unsigned char*)msg, msg_len, sizeof(text_base64));
 
-		manager_event_new_sms(PVT_ID(pvt), number, msg);
-		manager_event_new_sms_base64(PVT_ID(pvt), number, text_base64);
-		{
-			channel_var_t vars[] = 
+			manager_event_new_sms(PVT_ID(pvt), number, msg);
+			manager_event_new_sms_base64(PVT_ID(pvt), number, text_base64);
 			{
-				{ "SMS", msg } ,
-				{ "SMS_BASE64", text_base64 },
-				{ "CMGR", (char *)str },
-				{ NULL, NULL },
-			};
-			start_local_channel (pvt, "sms", number, vars);
+				channel_var_t vars[] =
+				{
+					{ "SMS", msg } ,
+					{ "SMS_BASE64", text_base64 },
+					{ "CMGR", (char *)str },
+					{ NULL, NULL },
+				};
+				start_local_channel (pvt, "sms", number, vars);
+			}
+		}
+		else
+		{
+			ast_log (LOG_ERROR, "[%s] Received '+CMGR' when expecting '%s' response to '%s', ignoring\n", PVT_ID(pvt),
+					at_res2str (ecmd->res), at_cmd2str (ecmd->cmd));
 		}
-	    }
-	    else
-	    {
-		ast_log (LOG_ERROR, "[%s] Received '+CMGR' when expecting '%s' response to '%s', ignoring\n", PVT_ID(pvt),
-				at_res2str (ecmd->res), at_cmd2str (ecmd->cmd));
-	    }
 	}
 	else
 	{
@@ -1387,7 +1395,7 @@ static int at_response_cusd (struct pvt * pvt, char * str, size_t len)
 	manager_event_message("DongleNewUSSDBase64", PVT_ID(pvt), text_base64);
 
 	{
-		channel_var_t vars[] = 
+		channel_var_t vars[] =
 		{
 			{ "USSD_TYPE", typebuf },
 			{ "USSD_TYPE_STR", ast_strdupa(typestr) },
@@ -1714,13 +1722,8 @@ int at_response (struct pvt* pvt, const struct iovec iov[2], int iovcnt, at_res_
 			ast_debug (5, "[%s] iovcnt == 2\n", PVT_ID(pvt));
 
 			str = alloca(len + 1);
-			if (!str)
-			{
-				ast_debug (1, "[%s] buffer overflow\n", PVT_ID(pvt));
-				return -1;
-			}
-			memcpy (str,                  iov[0].iov_base, iov[0].iov_len);
-			memcpy (str + iov[0].iov_len, iov[1].iov_base, iov[1].iov_len);
+			memcpy(str, iov[0].iov_base, iov[0].iov_len);
+			memcpy(str + iov[0].iov_len, iov[1].iov_base, iov[1].iov_len);
 		}
 		else
 		{
diff --git a/chan_dongle.c b/chan_dongle.c
index 84eef5c..01d17f7 100644
--- a/chan_dongle.c
+++ b/chan_dongle.c
@@ -35,7 +35,6 @@
 #include <config.h>
 #endif /* HAVE_CONFIG_H */
 
-
 #include <asterisk.h>
 ASTERISK_FILE_VERSION(__FILE__, "$Rev: " PACKAGE_REVISION " $")
 
@@ -45,10 +44,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Rev: " PACKAGE_REVISION " $")
 #include <asterisk/callerid.h>
 #include <asterisk/module.h>		/* AST_MODULE_LOAD_DECLINE ... */
 #include <asterisk/timing.h>		/* ast_timer_open() ast_timer_fd() */
-#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
-#include <asterisk/stasis_channels.h>
-#include <asterisk/format_cache.h>
-#endif
 
 #include <sys/stat.h>			/* S_IRUSR | S_IRGRP | S_IROTH */
 #include <termios.h>			/* struct termios tcgetattr() tcsetattr()  */
@@ -58,6 +53,11 @@ ASTERISK_FILE_VERSION(__FILE__, "$Rev: " PACKAGE_REVISION " $")
 
 #include "ast_compat.h"			/* asterisk compatibility fixes */
 
+#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
+#include <asterisk/stasis_channels.h>
+#include <asterisk/format_cache.h>
+#endif /* ^13+ */
+
 #include "chan_dongle.h"
 #include "at_response.h"		/* at_res_t */
 #include "at_queue.h"			/* struct at_queue_task_cmd at_queue_head_cmd() */
@@ -73,10 +73,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Rev: " PACKAGE_REVISION " $")
 
 EXPORT_DEF const char * const dev_state_strs[4] = { "stop", "restart", "remove", "start" };
 EXPORT_DEF public_state_t * gpublic;
-#if ASTERISK_VERSION_NUM >= 100000 && ASTERISK_VERSION_NUM < 130000 /* 10+..13- */
+#if ASTERISK_VERSION_NUM >= 100000 && ASTERISK_VERSION_NUM < 130000 /* 10-13 */
 EXPORT_DEF struct ast_format chan_dongle_format;
 EXPORT_DEF struct ast_format_cap * chan_dongle_format_cap;
-#endif
+#endif /* ^10-13 */
 
 static int public_state_init(struct public_state * state);
 
@@ -355,7 +355,7 @@ EXPORT_DEF void clean_read_data(const char * devname, int fd)
 	struct ringbuffer rb;
 	int iovcnt;
 	int t;
-	
+
 	rb_init (&rb, buf, sizeof (buf));
 	for (t = 0; at_wait(fd, &t); t = 0)
 	{
@@ -399,7 +399,7 @@ static void* do_monitor_phone (void* data)
 	ast_copy_string(dev, PVT_ID(pvt), sizeof(dev));
 
 	clean_read_data(dev, fd);
-	
+
 	/* schedule dongle initilization  */
 	if (at_enque_initialization (&pvt->sys_chan, CMD_AT))
 	{
@@ -535,39 +535,39 @@ static int pvt_discovery(struct pvt * pvt)
 		ast_copy_string(imei, CONF_UNIQ(pvt, imei), sizeof(imei));
 		ast_copy_string(imsi, CONF_UNIQ(pvt, imsi), sizeof(imsi));
 
-		ast_debug(3, "[%s] Trying ports discovery for%s%s%s%s\n", 
-			PVT_ID(pvt), 
-			imei[0] == 0 ? "" : " IMEI ", 
-			imei, 
-			imsi[0] == 0 ? "" : " IMSI ", 
+		ast_debug(3, "[%s] Trying ports discovery for%s%s%s%s\n",
+			PVT_ID(pvt),
+			imei[0] == 0 ? "" : " IMEI ",
+			imei,
+			imsi[0] == 0 ? "" : " IMSI ",
 			imsi
 			);
 		ast_mutex_unlock (&pvt->lock);
 //sleep(10); // test
 		resolved = pdiscovery_lookup(devname, imei, imsi, &data_tty, &audio_tty);
 		ast_mutex_lock (&pvt->lock);
-		
+
 		if(resolved) {
 			ast_copy_string (PVT_STATE(pvt, data_tty),  data_tty,  sizeof (PVT_STATE(pvt, data_tty)));
 			ast_copy_string (PVT_STATE(pvt, audio_tty), audio_tty, sizeof (PVT_STATE(pvt, audio_tty)));
 
 			ast_free(audio_tty);
 			ast_free(data_tty);
-			ast_verb (3, "[%s]%s%s%s%s found on data_tty=%s audio_tty=%s\n", 
-				PVT_ID(pvt), 
-				imei[0] == 0 ? "" : " IMEI ", 
-				imei, 
-				imsi[0] == 0 ? "" : " IMSI ", 
+			ast_verb (3, "[%s]%s%s%s%s found on data_tty=%s audio_tty=%s\n",
+				PVT_ID(pvt),
+				imei[0] == 0 ? "" : " IMEI ",
+				imei,
+				imsi[0] == 0 ? "" : " IMSI ",
 				imsi,
-				PVT_STATE(pvt, data_tty), 
+				PVT_STATE(pvt, data_tty),
 				PVT_STATE(pvt, audio_tty)
 				);
 		} else {
-			ast_debug(3, "[%s] Not found ports for%s%s%s%s\n", 
-				PVT_ID(pvt), 
-				imei[0] == 0 ? "" : " IMEI ", 
-				imei, 
-				imsi[0] == 0 ? "" : " IMSI ", 
+			ast_debug(3, "[%s] Not found ports for%s%s%s%s\n",
+				PVT_ID(pvt),
+				imei[0] == 0 ? "" : " IMEI ",
+				imei,
+				imsi[0] == 0 ? "" : " IMSI ",
 				imsi
 				);
 		}
@@ -860,17 +860,13 @@ EXPORT_DECL int pvt_enabled(const struct pvt * pvt)
 #/* */
 EXPORT_DEF int ready4voice_call(const struct pvt* pvt, const struct cpvt * current_cpvt, int opts)
 {
-	if(!pvt->connected 
-		|| 
-	   !pvt->initialized
-		|| 
-	   !pvt->has_voice 
-		|| 
-	   !pvt->gsm_registered 
-		|| 
-	   !pvt_enabled(pvt)
-	)
+	if(!pvt->connected
+		|| !pvt->initialized
+		|| !pvt->has_voice
+		|| !pvt->gsm_registered
+		|| !pvt_enabled(pvt)) {
 		return 0;
+	}
 
 	return is_dial_possible2(pvt, opts, current_cpvt);
 }
@@ -1468,29 +1464,20 @@ static int pvt_reconfigure(struct pvt * pvt, const pvt_config_t * settings, rest
 		/* check what changes require starting or stopping */
 		if(pvt->desired_state != SCONFIG(settings, initstate)) {
 			pvt->desired_state = SCONFIG(settings, initstate);
-			
+
 			rv = pvt_time4restate(pvt);
 			pvt->restart_time = rv ? RESTATE_TIME_NOW : when;
 		}
 
 		/* check what config changes require restaring */
-		else if(
-		   strcmp(UCONFIG(settings, audio_tty), CONF_UNIQ(pvt, audio_tty))
-			||
-		   strcmp(UCONFIG(settings, data_tty), CONF_UNIQ(pvt, data_tty))
-			||
-		   strcmp(UCONFIG(settings, imei), CONF_UNIQ(pvt, imei))
-			||
-		   strcmp(UCONFIG(settings, imsi), CONF_UNIQ(pvt, imsi))
-			||
-		   SCONFIG(settings, u2diag) != CONF_SHARED(pvt, u2diag)
-			||
-		   SCONFIG(settings, resetdongle) != CONF_SHARED(pvt, resetdongle)
-			||
-		   SCONFIG(settings, smsaspdu) != CONF_SHARED(pvt, smsaspdu)
-			||
-		   SCONFIG(settings, callwaiting) != CONF_SHARED(pvt, callwaiting)
-		   )
+		else if(strcmp(UCONFIG(settings, audio_tty), CONF_UNIQ(pvt, audio_tty))
+			|| strcmp(UCONFIG(settings, data_tty), CONF_UNIQ(pvt, data_tty))
+			|| strcmp(UCONFIG(settings, imei), CONF_UNIQ(pvt, imei))
+			|| strcmp(UCONFIG(settings, imsi), CONF_UNIQ(pvt, imsi))
+			|| SCONFIG(settings, u2diag) != CONF_SHARED(pvt, u2diag)
+			|| SCONFIG(settings, resetdongle) != CONF_SHARED(pvt, resetdongle)
+			|| SCONFIG(settings, smsaspdu) != CONF_SHARED(pvt, smsaspdu)
+			|| SCONFIG(settings, callwaiting) != CONF_SHARED(pvt, callwaiting))
 		{
 			/* TODO: schedule restart */
 			pvt->desired_state = DEV_STATE_RESTARTED;
@@ -1656,7 +1643,7 @@ static int load_module()
 static int public_state_init(struct public_state * state)
 {
 	int rv = AST_MODULE_LOAD_DECLINE;
-	
+
 	AST_RWLIST_HEAD_INIT(&state->devices);
 	ast_mutex_init(&state->discovery_lock);
 
@@ -1683,7 +1670,7 @@ static int public_state_init(struct public_state * state)
 			}
 			ast_format_cap_add(channel_tech.capabilities, &chan_dongle_format);
 			chan_dongle_format_cap = channel_tech.capabilities;
-#endif
+#endif /* ^10-13 */
 
 			/* register our channel type */
 			if(ast_channel_register(&channel_tech) == 0)
@@ -1698,11 +1685,11 @@ static int public_state_init(struct public_state * state)
 			else
 			{
 #if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
-			        ao2_cleanup(channel_tech.capabilities);
-			        channel_tech.capabilities = NULL;
+				ao2_cleanup(channel_tech.capabilities);
+				channel_tech.capabilities = NULL;
 #elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
 				channel_tech.capabilities = ast_format_cap_destroy(channel_tech.capabilities);
-#endif
+#endif /* ^10-13 */
 				ast_log (LOG_ERROR, "Unable to register channel class %s\n", channel_tech.type);
 			}
 			discovery_stop(state);
@@ -1731,12 +1718,11 @@ static void public_state_fini(struct public_state * state)
 	/* First, take us out of the channel loop */
 	ast_channel_unregister (&channel_tech);
 #if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
-        ao2_cleanup(channel_tech.capabilities);
-        channel_tech.capabilities = NULL;
-
+	ao2_cleanup(channel_tech.capabilities);
+	channel_tech.capabilities = NULL;
 #elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
 	channel_tech.capabilities = ast_format_cap_destroy(channel_tech.capabilities);
-#endif
+#endif /* ^10-13 */
 
 	/* Unregister the CLI & APP & MANAGER */
 
@@ -1748,7 +1734,7 @@ static void public_state_fini(struct public_state * state)
 
 	discovery_stop(state);
 	devices_destroy(state);
-	
+
 //	ast_mutex_destroy(&state->round_robin_mtx);
 	ast_mutex_destroy(&state->discovery_lock);
 	AST_RWLIST_HEAD_DESTROY(&state->devices);
@@ -1759,7 +1745,7 @@ static int unload_module()
 
 	public_state_fini(gpublic);
 	pdiscovery_fini();
-	
+
 	ast_free(gpublic);
 	gpublic = NULL;
 	return 0;
@@ -1785,13 +1771,13 @@ static int reload_module()
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, MODULE_DESCRIPTION,
 #if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
 		.support_level = AST_MODULE_SUPPORT_EXTENDED,
-#endif
+#endif /* ^13+ */
 		.load = load_module,
 		.unload = unload_module,
 		.reload = reload_module,
 #if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
 		.load_pri = AST_MODPRI_CHANNEL_DRIVER,
-#endif
+#endif /* ^13+ */
 	       );
 
 //AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY, MODULE_DESCRIPTION);
diff --git a/chan_dongle.h b/chan_dongle.h
index a94cfbb..b6e0436 100644
--- a/chan_dongle.h
+++ b/chan_dongle.h
@@ -16,7 +16,7 @@
 #include <asterisk/lock.h>
 #include <asterisk/linkedlists.h>
 
-#include <ast_compat.h>
+#include "ast_compat.h"				/* asterisk compatibility fixes */
 
 #include "mixbuffer.h"				/* struct mixbuffer */
 //#include "ringbuffer.h"				/* struct ringbuffer */
@@ -38,12 +38,12 @@ INLINE_DECL const char * dev_state2str_msg(dev_state_t state)
 	return enum2str(state, states, ITEMS_OF(states));
 }
 
-#if ASTERISK_VERSION_NUM >= 100000 && ASTERISK_VERSION_NUM < 130000 /* 10+..13- */
+#if ASTERISK_VERSION_NUM >= 100000 && ASTERISK_VERSION_NUM < 130000 /* 10-13 */
 /* Only linear is allowed */
 EXPORT_DECL struct ast_format chan_dongle_format;
 //EXPORT_DEF struct ast_format chan_dongle_format;
 EXPORT_DECL struct ast_format_cap * chan_dongle_format_cap;
-#endif
+#endif /* ^10-13 */
 
 typedef enum {
 	RESTATE_TIME_NOW	= 0,
@@ -131,7 +131,7 @@ typedef struct pvt
 //	char			a_read_buf[FRAME_SIZE + AST_FRIENDLY_OFFSET];	/*!< audio read buffer */
 //	struct ast_frame	a_read_frame;			/*!< readed frame buffer */
 
-	
+
 	char			dtmf_digit;			/*!< last DTMF digit */
 	struct timeval		dtmf_begin_time;		/*!< time of begin of last DTMF digit */
 	struct timeval		dtmf_end_time;			/*!< time of end of last DTMF digit */
@@ -139,7 +139,7 @@ typedef struct pvt
 	int			timeout;			/*!< used to set the timeout for data */
 #define DATA_READ_TIMEOUT	10000				/* 10 seconds */
 
-	unsigned long		channel_instanse;		/*!< number of channels created on this device */
+	unsigned long		channel_instance;		/*!< number of channels created on this device */
 	unsigned int		rings;				/*!< ring/ccwa  number distributed to at_response_clcc() */
 
 	/* device caps */
diff --git a/channel.c b/channel.c
index 1875748..a14bcca 100644
--- a/channel.c
+++ b/channel.c
@@ -1,9 +1,9 @@
-/* 
+/*
    Copyright (C) 2009 - 2010
-   
+
    Artem Makhutov <artem@makhutov.org>
    http://www.makhutov.org
-   
+
    Dmitry Vagin <dmitry2004@yandex.ru>
 
    bg <bg_one@mail.ru>
@@ -12,10 +12,6 @@
 #include <config.h>
 #endif /* HAVE_CONFIG_H */
 
-#ifndef ASTERISK_VERSION_NUM
-#error ASTERISK_VERSION_NUM is not set, please supply -D ASTERISK_VERSION_NUM=100501 for version 10.5.1
-#endif
-
 #include <asterisk.h>
 #include <asterisk/dsp.h>			/* ast_dsp_digitreset() */
 #include <asterisk/pbx.h>			/* pbx_builtin_setvar_helper() */
@@ -29,7 +25,7 @@
 #if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
 #include <asterisk/stasis_channels.h>
 #include <asterisk/format_cache.h>
-#endif
+#endif /* ^13+ */
 
 #include "channel.h"
 #include "chan_dongle.h"
@@ -100,34 +96,45 @@ EXPORT_DEF int channels_loop(struct pvt * pvt, const struct ast_channel * reques
 	/* FIXME: requestor may be just proxy/masquerade for real channel */
 	//	use ast_bridged_channel(chan) ?
 	//	use requestor->tech->get_base_channel() ?
+	struct cpvt *tmp;
 	return (requestor
 		&& ast_channel_tech(requestor) == &channel_tech
-		&& ast_channel_tech_pvt(requestor)
-		&& ((struct cpvt*) ast_channel_tech_pvt(requestor))->pvt == pvt)
+		&& (tmp = ast_channel_tech_pvt(requestor))
+		&& tmp->pvt == pvt)
 		? 1
 		: 0;
 }
 
 #if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
-static struct ast_channel * channel_request (attribute_unused const char * type, struct ast_format_cap * cap, const struct ast_assigned_ids * assignedids, const struct ast_channel * requestor, const char * data, int * cause)
+static struct ast_channel * channel_request(
+		attribute_unused const char * type, struct ast_format_cap * cap,
+		const struct ast_assigned_ids * assignedids,
+		const struct ast_channel * requestor, const char * data, int * cause)
 #elif ASTERISK_VERSION_NUM >= 110000 /* 11+ */
-static struct ast_channel * channel_request (attribute_unused const char * type, struct ast_format_cap * cap, const struct ast_channel * requestor, const char * data, int * cause)
+static struct ast_channel * channel_request(
+		attribute_unused const char * type, struct ast_format_cap * cap,
+		const struct ast_channel * requestor, const char * data, int * cause)
 #elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
-static struct ast_channel * channel_request (attribute_unused const char * type, struct ast_format_cap * cap, const struct ast_channel * requestor, void * data, int * cause)
+static struct ast_channel * channel_request(
+		attribute_unused const char * type, struct ast_format_cap * cap,
+		const struct ast_channel * requestor, void * data, int * cause)
 #elif ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
-//   TODO: simplify by move common code to functions
-static struct ast_channel * channel_request (attribute_unused const char * type, format_t format, const struct ast_channel * requestor, void * data, int * cause)
+static struct ast_channel * channel_request(
+		attribute_unused const char * type, format_t format,
+		const struct ast_channel * requestor, void * data, int * cause)
 #else /* 1.8- */
-/* TODO: add check when request 'holdother' what requestor is not on same device for 1.6 */
-static struct ast_channel * channel_request (attribute_unused const char * type, int format, void * data, int * cause)
-#endif
+static struct ast_channel * channel_request(
+		attribute_unused const char * type, int format, void * data, int * cause)
+#endif /* ^1.8- */
 {
+/* TODO: simplify by moving common code to functions */
+/* TODO: add check when request 'holdother' what requestor is not on same device for 1.6 */
 #if ASTERISK_VERSION_NUM >= 10800 && ASTERISK_VERSION_NUM < 100000 /* 1.8+ .. 10- */
 	format_t oldformat;
 #elif ASTERISK_VERSION_NUM < 10800 /* 1.8- */
 	int oldformat;
 	const struct ast_channel * requestor = NULL;
-#endif
+#endif /* ^1.8- */
 	char * dest_dev;
 	const char * dest_num;
 	struct ast_channel * channel = NULL;
@@ -146,23 +153,27 @@ static struct ast_channel * channel_request (attribute_unused const char * type,
 	if (ast_format_cap_iscompatible_format(cap, ast_format_slin) != AST_FORMAT_CMP_EQUAL)
 #elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
 	if (!ast_format_cap_iscompatible(cap, &chan_dongle_format))
-#else
+#else /* 10- */
 	oldformat = format;
 	format &= AST_FORMAT_SLINEAR;
 	if (!format)
-#endif
+#endif /* ^10- */
 	{
 #if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
 		struct ast_str *codec_buf = ast_str_alloca(64);
-		ast_log (LOG_WARNING, "Asked to get a channel of unsupported format '%s'\n", ast_format_cap_get_names(cap, &codec_buf));
+		ast_log(LOG_WARNING, "Asked to get a channel of unsupported format '%s'\n",
+				ast_format_cap_get_names(cap, &codec_buf));
 #elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
 		char buf[255];
-		ast_log (LOG_WARNING, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple (buf, 255, cap));
+		ast_log(LOG_WARNING, "Asked to get a channel of unsupported format '%s'\n",
+				ast_getformatname_multiple(buf, 255, cap));
 #elif ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
-		ast_log (LOG_WARNING, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname (oldformat));
-#else
-		ast_log (LOG_WARNING, "Asked to get a channel of unsupported format '%d'\n", oldformat);
-#endif
+		ast_log(LOG_WARNING, "Asked to get a channel of unsupported format '%s'\n",
+				ast_getformatname(oldformat));
+#else /* 1.8- */
+		ast_log(LOG_WARNING, "Asked to get a channel of unsupported format '%d'\n",
+				oldformat);
+#endif /* ^1.8- */
 		*cause = AST_CAUSE_FACILITY_NOT_IMPLEMENTED;
 		return NULL;
 	}
@@ -175,16 +186,19 @@ static struct ast_channel * channel_request (attribute_unused const char * type,
 
 #if ASTERISK_VERSION_NUM >= 10800
 	pvt = find_device_by_resource(dest_dev, opts, requestor, &exists);
-#else
+#else /* 1.8- */
 	pvt = find_device_by_resource(dest_dev, opts, NULL, &exists);
-#endif
+#endif /* ^1.8- */
+
 	if(pvt)
 	{
 #if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
-		channel = new_channel (pvt, AST_STATE_DOWN, NULL, pvt_get_pseudo_call_idx(pvt), CALL_DIR_OUTGOING, CALL_STATE_INIT, NULL, assignedids, requestor);
-#else
-		channel = new_channel (pvt, AST_STATE_DOWN, NULL, pvt_get_pseudo_call_idx(pvt), CALL_DIR_OUTGOING, CALL_STATE_INIT, NULL, requestor);
-#endif
+		channel = new_channel(pvt, AST_STATE_DOWN, NULL, pvt_get_pseudo_call_idx(pvt),
+				CALL_DIR_OUTGOING, CALL_STATE_INIT, NULL, assignedids, requestor);
+#else /* 13- */
+		channel = new_channel(pvt, AST_STATE_DOWN, NULL, pvt_get_pseudo_call_idx(pvt),
+				CALL_DIR_OUTGOING, CALL_STATE_INIT, NULL, requestor);
+#endif /* ^13- */
 		ast_mutex_unlock (&pvt->lock);
 		if(!channel)
 		{
@@ -204,10 +218,10 @@ static struct ast_channel * channel_request (attribute_unused const char * type,
 
 #/* */
 #if ASTERISK_VERSION_NUM >= 110000 /* 11+ */
-static int channel_call (struct ast_channel* channel, const char *dest, attribute_unused int timeout)
-#else
-static int channel_call (struct ast_channel* channel, char* dest, attribute_unused int timeout)
-#endif
+static int channel_call(struct ast_channel* channel, const char *dest, attribute_unused int timeout)
+#else /* 11- */
+static int channel_call(struct ast_channel* channel, char* dest, attribute_unused int timeout)
+#endif /* ^11- */
 {
 	struct cpvt* cpvt = ast_channel_tech_pvt(channel);
 	struct pvt* pvt;
@@ -251,11 +265,11 @@ static int channel_call (struct ast_channel* channel, char* dest, attribute_unus
 	{
 		if (CONF_SHARED(pvt, callingpres) < 0)
 		{
-#if ASTERISK_VERSION_NUM >= 10800
+#if ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
 			clir = ast_channel_connected(channel)->id.number.presentation;
-#else
+#else /* 1.8- */
 			clir = channel->cid.cid_pres;
-#endif
+#endif /* ^1.8- */
 		}
 		else
 		{
@@ -487,8 +501,9 @@ static void iov_write(struct pvt* pvt, int fd, struct iovec * iov, int iovcnt)
 			if((errno == EINTR || errno == EAGAIN))
 			{
 				--count;
-				if(count != 0)
-				    goto again;
+				if(count != 0) {
+					goto again;
+				}
 				ast_debug (1, "[%s] Deadlock avoided for write!\n", PVT_ID(pvt));
 			}
 			break;
@@ -616,7 +631,7 @@ static void write_conference(struct pvt * pvt, const char * buffer, size_t lengt
 #else /* 1.8- */
 #define subclass_codec		subclass
 #define subclass_integer	subclass
-#endif
+#endif /* ^1.8- */
 
 #/* */
 static struct ast_frame* channel_read (struct ast_channel* channel)
@@ -661,9 +676,9 @@ static struct ast_frame* channel_read (struct ast_channel* channel)
 		cpvt->a_read_frame.subclass.format = ao2_bump(ast_format_slin);
 #elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
 		ast_format_copy(&cpvt->a_read_frame.subclass.format, &chan_dongle_format);
-#else
+#else /* 10- */
 		cpvt->a_read_frame.subclass_codec = AST_FORMAT_SLINEAR;
-#endif
+#endif /* ^10- */
 		cpvt->a_read_frame.data.ptr = cpvt->a_read_buf + AST_FRIENDLY_OFFSET;
 		cpvt->a_read_frame.offset = AST_FRIENDLY_OFFSET;
 		cpvt->a_read_frame.src = AST_MODULE;
@@ -733,9 +748,9 @@ static struct ast_frame* channel_read (struct ast_channel* channel)
 						f->subclass_integer = 0;
 					}
 					else if(f->subclass_integer == pvt->dtmf_digit
-							&& 
+							&&
 						!ast_tvzero(pvt->dtmf_end_time)
-							&& 
+							&&
 						ast_tvdiff_ms(ast_tvnow(), pvt->dtmf_end_time) < CONF_SHARED(pvt, mindtmfinterval))
 					{
 						ast_debug(1, "[%s] DTMF char %c ignored min interval %d > %ld\n", PVT_ID(pvt), f->subclass_integer, CONF_SHARED(pvt, mindtmfinterval), (long)ast_tvdiff_ms(ast_tvnow(), pvt->dtmf_end_time));
@@ -778,12 +793,15 @@ static int channel_write (struct ast_channel* channel, struct ast_frame* f)
 	int gains[2];
 
 #if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
-	if (f->frametype != AST_FRAME_VOICE || ast_format_cmp(f->subclass.format, ast_format_slin) != AST_FORMAT_CMP_EQUAL)
+	if (f->frametype != AST_FRAME_VOICE
+			|| ast_format_cmp(f->subclass.format, ast_format_slin) != AST_FORMAT_CMP_EQUAL)
 #elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
-	if (f->frametype != AST_FRAME_VOICE || f->subclass.format.id != AST_FORMAT_SLINEAR)
+	if (f->frametype != AST_FRAME_VOICE
+			|| f->subclass.format.id != AST_FORMAT_SLINEAR)
 #else /* 10- */
-	if (f->frametype != AST_FRAME_VOICE || f->subclass_codec != AST_FORMAT_SLINEAR)
-#endif
+	if (f->frametype != AST_FRAME_VOICE
+			|| f->subclass_codec != AST_FORMAT_SLINEAR)
+#endif /* ^10- */
 	{
 		return 0;
 	}
@@ -816,9 +834,9 @@ static int channel_write (struct ast_channel* channel, struct ast_frame* f)
 	{
 #if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
 		RAII_VAR(struct ast_channel *, bridged, ast_channel_bridge_peer(channel), ast_channel_cleanup);
-#else
-		struct ast_channel* bridged = ast_bridged_channel(channel);
-#endif
+#else /* 13- */
+		struct ast_channel *bridged = ast_bridged_channel(channel);
+#endif /* ^13- */
 		struct cpvt *tmp_cpvt;
 
 		CPVT_SET_FLAGS(cpvt, CALL_FLAG_BRIDGE_CHECK);
@@ -840,8 +858,8 @@ static int channel_write (struct ast_channel* channel, struct ast_frame* f)
 	{
 		if(f->datalen)
 		{
-			/** try to minimize of ast_frame_adjust_volume() calls: 
-			 *  one hand we must obey txgain but with other divide gain to 
+			/** try to minimize of ast_frame_adjust_volume() calls:
+			 *  one hand we must obey txgain but with other divide gain to
 			 *  number of mixed channels. In some cases one call of ast_frame_adjust_volume() enough
 			*/
 
@@ -973,9 +991,9 @@ static int channel_fixup (struct ast_channel* oldchannel, struct ast_channel* ne
 #/* FIXME: must modify in conjuction with state on call not whole device? */
 #if ASTERISK_VERSION_NUM >= 110000 /* 11+ */
 static int channel_devicestate (const char *data)
-#else
+#else /* 11- */
 static int channel_devicestate (void* data)
-#endif
+#endif /* ^11- */
 {
 	char*	device;
 	struct pvt*	pvt;
@@ -1172,7 +1190,7 @@ EXPORT_DEF void change_channel_state(struct cpvt * cpvt, unsigned newstate, int
 static void set_channel_vars(struct pvt* pvt, struct ast_channel* channel)
 {
 	unsigned idx;
-	channel_var_t dev_vars[] = 
+	channel_var_t dev_vars[] =
 	{
 		{ "DONGLENAME", PVT_ID(pvt) },
 		{ "DONGLEPROVIDER", pvt->provider_name },
@@ -1183,25 +1201,29 @@ static void set_channel_vars(struct pvt* pvt, struct ast_channel* channel)
 
 #if ASTERISK_VERSION_NUM >= 110000 /* 11+  */
 	ast_channel_language_set(channel, CONF_SHARED(pvt, language));
-#else
+#else /* 11- */
 	//TODO uncomment and fix
 	//ast_string_field_set (channel, language, CONF_SHARED(pvt, language);
-#endif
+#endif /* ^11- */
 
 	for(idx = 0; idx < ITEMS_OF(dev_vars); ++idx)
 		pbx_builtin_setvar_helper (channel, dev_vars[idx].name, dev_vars[idx].value);
-
 }
 
-#/* NOTE: called from device and current levels with locked pvt */
+/* NOTE: called from device and current levels with locked pvt */
 #if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
-EXPORT_DEF struct ast_channel* new_channel (struct pvt* pvt, int ast_state, const char* cid_num, int call_idx, unsigned dir, call_state_t state, const char * dnid, const struct ast_assigned_ids *assignedids, attribute_unused const struct ast_channel * requestor)
-#else
-EXPORT_DEF struct ast_channel* new_channel (struct pvt* pvt, int ast_state, const char* cid_num, int call_idx, unsigned dir, call_state_t state, const char * dnid, attribute_unused const struct ast_channel * requestor)
-#endif
+EXPORT_DEF struct ast_channel* new_channel(
+		struct pvt* pvt, int ast_state, const char* cid_num, int call_idx,
+		unsigned dir, call_state_t state, const char * dnid,
+		const struct ast_assigned_ids *assignedids,
+		attribute_unused const struct ast_channel * requestor)
+#else /* 13- */
+EXPORT_DEF struct ast_channel* new_channel(
+		struct pvt* pvt, int ast_state, const char* cid_num, int call_idx,
+		unsigned dir, call_state_t state, const char * dnid,
+		attribute_unused const struct ast_channel * requestor)
+#endif /* ^13- */
 {
-//        struct ast_channel * channel = new_channel (pvt, AST_STATE_RING, number, call_idx, CALL_DIR_INCOMING, state, pvt->has_subscriber_number ? pvt->subscriber_number : CONF_SHARED(pvt, exten), $
-
 	struct ast_channel* channel;
 	struct cpvt * cpvt;
 
@@ -1209,16 +1231,29 @@ EXPORT_DEF struct ast_channel* new_channel (struct pvt* pvt, int ast_state, cons
 	if (cpvt)
 	{
 #if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
-                channel = ast_channel_alloc (1, ast_state, cid_num, PVT_ID(pvt), NULL, dnid, CONF_SHARED(pvt, context), assignedids, requestor, 0, "%s/%s-%02u%08lx", channel_tech.type, PVT_ID(pvt), call_idx, pvt->channel_instanse);
+		channel = ast_channel_alloc(
+				1, ast_state, cid_num, PVT_ID(pvt), NULL, dnid,
+				CONF_SHARED(pvt, context), assignedids, requestor, 0,
+				"%s/%s-%02u%08lx", channel_tech.type, PVT_ID(pvt),
+				call_idx, pvt->channel_instance);
 #elif ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
-		channel = ast_channel_alloc (1, ast_state, cid_num, PVT_ID(pvt), NULL, dnid, CONF_SHARED(pvt, context), requestor ? ast_channel_linkedid(requestor): NULL, 0, "%s/%s-%02u%08lx", channel_tech.type, PVT_ID(pvt), call_idx, pvt->channel_instanse);
-#else
-		channel = ast_channel_alloc (1, ast_state, cid_num, PVT_ID(pvt), NULL, dnid, CONF_SHARED(pvt, context), 0, "%s/%s-%02u%08lx", channel_tech.type, PVT_ID(pvt), call_idx, pvt->channel_instanse);
-#endif
+		channel = ast_channel_alloc(
+				1, ast_state, cid_num, PVT_ID(pvt), NULL, dnid,
+				CONF_SHARED(pvt, context),
+				requestor ? ast_channel_linkedid(requestor) : NULL, 0,
+				"%s/%s-%02u%08lx", channel_tech.type, PVT_ID(pvt),
+				call_idx, pvt->channel_instance);
+#else /* 1.8- */
+		channel = ast_channel_alloc(
+				1, ast_state, cid_num, PVT_ID(pvt), NULL, dnid,
+				CONF_SHARED(pvt, context), 0,
+				"%s/%s-%02u%08lx", channel_tech.type, PVT_ID(pvt),
+				call_idx, pvt->channel_instance);
+#endif /* ^1.8- */
 		if (channel)
 		{
 			cpvt->channel = channel;
-			pvt->channel_instanse++;
+			pvt->channel_instance++;
 
 			ast_channel_tech_pvt_set(channel, cpvt);
 			ast_channel_tech_set(channel, &channel_tech);
@@ -1239,7 +1274,7 @@ EXPORT_DEF struct ast_channel* new_channel (struct pvt* pvt, int ast_state, cons
 			channel->nativeformats	= AST_FORMAT_SLINEAR;
 			channel->writeformat	= AST_FORMAT_SLINEAR;
 			channel->readformat	= AST_FORMAT_SLINEAR;
-#endif
+#endif /* ^10- */
 
 			if (ast_state == AST_STATE_RING)
 			{
@@ -1329,14 +1364,14 @@ EXPORT_DEF void start_local_channel (struct pvt* pvt, const char* exten, const c
 	snprintf (channel_name, sizeof (channel_name), "%s@%s", exten, CONF_SHARED(pvt, context));
 
 #if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
-	channel = ast_request ("Local", channel_tech.capabilities, NULL, NULL, channel_name, &cause);
+	channel = ast_request("Local", channel_tech.capabilities, NULL, NULL, channel_name, &cause);
 #elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
-	channel = ast_request ("Local", chan_dongle_format_cap, NULL, channel_name, &cause);
+	channel = ast_request("Local", chan_dongle_format_cap, NULL, channel_name, &cause);
 #elif ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
-	channel = ast_request ("Local", AST_FORMAT_AUDIO_MASK, NULL, channel_name, &cause);
+	channel = ast_request("Local", AST_FORMAT_AUDIO_MASK, NULL, channel_name, &cause);
 #else /* 1.8- */
-	channel = ast_request ("Local", AST_FORMAT_AUDIO_MASK, channel_name, &cause);
-#endif
+	channel = ast_request("Local", AST_FORMAT_AUDIO_MASK, channel_name, &cause);
+#endif /* ^1.8- */
 	if (channel)
 	{
 		set_channel_vars(pvt, channel);
@@ -1479,7 +1514,7 @@ static int channel_func_write(struct ast_channel* channel, const char* function,
 			{
 				pvt_dsp_setup(pvt, PVT_ID(pvt), val);
 			}
-			
+
 			ast_mutex_unlock(&cpvt->pvt->lock);
 		}
 		else
@@ -1500,7 +1535,7 @@ EXPORT_DEF struct ast_channel_tech channel_tech =
 	.description		= MODULE_DESCRIPTION,
 #if ASTERISK_VERSION_NUM < 100000 /* 10- */
 	.capabilities		= AST_FORMAT_SLINEAR,
-#endif
+#endif /* ^10- */
 	.requester		= channel_request,
 	.call			= channel_call,
 	.hangup			= channel_hangup,
diff --git a/channel.h b/channel.h
index 702e3f2..3ad75a2 100644
--- a/channel.h
+++ b/channel.h
@@ -7,6 +7,8 @@
 #include <asterisk.h>
 #include <asterisk/frame.h>		/* enum ast_control_frame_type */
 
+#include "ast_compat.h"			/* asterisk compatibility fixes */
+
 #include "export.h"			/* EXPORT_DECL EXPORT_DEF */
 
 
@@ -22,10 +24,17 @@ struct cpvt;
 EXPORT_DECL struct ast_channel_tech channel_tech;
 
 #if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
-EXPORT_DECL struct ast_channel* new_channel (struct pvt * pvt, int ast_state, const char * cid_num, int call_idx, unsigned dir, unsigned state, const char * exten, const struct ast_assigned_ids *assignedids, const struct ast_channel * requestor);
-#else
-EXPORT_DECL struct ast_channel* new_channel (struct pvt * pvt, int ast_state, const char * cid_num, int call_idx, unsigned dir, unsigned state, const char * exten, const struct ast_channel * requestor);
-#endif
+EXPORT_DECL struct ast_channel* new_channel(
+		struct pvt * pvt, int ast_state, const char * cid_num, int call_idx,
+		unsigned dir, unsigned state, const char * exten,
+		const struct ast_assigned_ids *assignedids,
+		const struct ast_channel * requestor);
+#else /* 13- */
+EXPORT_DECL struct ast_channel* new_channel(
+		struct pvt * pvt, int ast_state, const char * cid_num, int call_idx,
+		unsigned dir, unsigned state, const char * exten,
+		const struct ast_channel * requestor);
+#endif /* ^13- */
 EXPORT_DECL int queue_control_channel (struct cpvt * cpvt, enum ast_control_frame_type control);
 EXPORT_DECL int queue_hangup (struct ast_channel * channel, int hangupcause);
 EXPORT_DECL void start_local_channel (struct pvt * pvt, const char * exten, const char * number, channel_var_t * vars);
diff --git a/char_conv.c b/char_conv.c
index 2a4be70..f1f4721 100644
--- a/char_conv.c
+++ b/char_conv.c
@@ -78,7 +78,7 @@ static ssize_t hexstr_to_8bitchars (const char* in, size_t in_length, char* out,
 		return -ENOMEM;
 	}
 	out_size = in_length;
-	
+
 	for (; in_length; --in_length)
 	{
 		d1 = parse_hexdigit(*in++);
@@ -105,7 +105,7 @@ static ssize_t chars8bit_to_hexstr (const char* in, size_t in_length, char* out,
 		return -1;
 	}
 	out_size = in_length * 2;
-	
+
 	for (; in_length; --in_length, ++in2)
 	{
 		*out++ = hex_table[*in2 >> 4];
diff --git a/cli.c b/cli.c
index 4c25562..b13e222 100644
--- a/cli.c
+++ b/cli.c
@@ -1,9 +1,9 @@
-/* 
+/*
    Copyright (C) 2009 - 2010
-   
+
    Artem Makhutov <artem@makhutov.org>
    http://www.makhutov.org
-   
+
    Dmitry Vagin <dmitry2004@yandex.ru>
 
    bg <bg_one@mail.ru>
@@ -12,15 +12,12 @@
 #include <config.h>
 #endif /* HAVE_CONFIG_H */
 
-#ifndef ASTERISK_VERSION_NUM
-#error ASTERISK_VERSION_NUM is not set, please supply \
-	-D ASTERISK_VERSION_NUM=100501 for version 10.5.1
-#endif
-
 #include <asterisk.h>
 #include <asterisk/cli.h>			/* struct ast_cli_entry; struct ast_cli_args */
 #include <asterisk/callerid.h>			/* ast_describe_caller_presentation() */
 
+#include "ast_compat.h"				/* asterisk compatibility fixes */
+
 #include "cli.h"
 #include "chan_dongle.h"			/* devices */
 #include "helpers.h"				/* ITEMS_OF() send_ccwa_set() send_reset() send_sms() send_ussd() */
@@ -229,7 +226,7 @@ static char* cli_show_device_state (struct ast_cli_entry* e, int cmd, struct ast
 		ast_cli (a->fd, "  Current device state    : %s\n", dev_state2str(pvt->current_state) );
 		ast_cli (a->fd, "  Desired device state    : %s\n", dev_state2str(pvt->desired_state) );
 		ast_cli (a->fd, "  When change state       : %s\n", restate2str_msg(pvt->restart_time) );
-		
+
 		ast_cli (a->fd, "  Calls/Channels          : %u\n", PVT_STATE(pvt, chansno));
 		ast_cli (a->fd, "    Active                : %u\n", PVT_STATE(pvt, chan_count[CALL_STATE_ACTIVE]));
 		ast_cli (a->fd, "    Held                  : %u\n", PVT_STATE(pvt, chan_count[CALL_STATE_ONHOLD]));
@@ -337,10 +334,10 @@ static char* cli_show_device_statistics (struct ast_cli_entry* e, int cmd, struc
 /*
 		ast_cli (a->fd, "  ACD                         : %d\n",
 			getACD(
-				PVT_STAT(pvt, calls_answered[CALL_DIR_OUTGOING]) 
-				+ PVT_STAT(pvt, calls_answered[CALL_DIR_INCOMING]), 
+				PVT_STAT(pvt, calls_answered[CALL_DIR_OUTGOING])
+				+ PVT_STAT(pvt, calls_answered[CALL_DIR_INCOMING]),
 
-				PVT_STAT(pvt, calls_duration[CALL_DIR_OUTGOING]) 
+				PVT_STAT(pvt, calls_duration[CALL_DIR_OUTGOING])
 				+ PVT_STAT(pvt, calls_duration[CALL_DIR_INCOMING])
 				)
 			);
@@ -556,11 +553,11 @@ static char * cli_pdu(struct ast_cli_entry * e, int cmd, struct ast_cli_args * a
 	return CLI_SUCCESS;
 }
 
-#if ASTERISK_VERSION_NUM >= 10800
+#if ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
 typedef const char * const * ast_cli_complete2_t;
-#else
+#else /* 1.8- */
 typedef char * const * ast_cli_complete2_t;
-#endif
+#endif /* ^1.8- */
 
 static char* cli_ccwa_set (struct ast_cli_entry* e, int cmd, struct ast_cli_args* a)
 {
@@ -843,7 +840,7 @@ static char * cli_discovery(struct ast_cli_entry * e, int cmd, struct ast_cli_ar
 	const char * imsi;
 	int imeilen;
 	int imsilen;
-	
+
 	switch (cmd) {
 		case CLI_INIT:
 			e->command =	"dongle discovery";
@@ -908,7 +905,7 @@ static char * cli_discovery(struct ast_cli_entry * e, int cmd, struct ast_cli_ar
 	}
 	pdiscovery_list_end();
 	AST_RWLIST_UNLOCK(&gpublic->devices);
-	
+
 	return CLI_SUCCESS;
 }
 
diff --git a/cpvt.c b/cpvt.c
index 762d9fc..e0dc9db 100644
--- a/cpvt.c
+++ b/cpvt.c
@@ -65,7 +65,7 @@ EXPORT_DEF struct cpvt * cpvt_alloc(struct pvt * pvt, int call_idx, unsigned dir
 				pvt_on_create_1st_channel(pvt);
 			PVT_STATE(pvt, chansno)++;
 			PVT_STATE(pvt, chan_count[cpvt->state])++;
-			
+
 
 
 			ast_debug (3, "[%s] create cpvt for call_idx %d dir %d state '%s'\n",  PVT_ID(pvt), call_idx, dir, call_state2str(state));
diff --git a/dc_config.c b/dc_config.c
index a57b00e..806f789 100644
--- a/dc_config.c
+++ b/dc_config.c
@@ -8,7 +8,7 @@
 #include "dc_config.h"
 #include <asterisk/callerid.h>				/* ast_parse_caller_presentation() */
 
-static struct ast_jb_conf jbconf_default = 
+static struct ast_jb_conf jbconf_default =
 {
 	.flags			= 0,
 	.max_size		= -1,
@@ -22,7 +22,7 @@ static const char * const dtmf_values[] = { "off", "inband", "relax" };
 
 EXPORT_DEF int dc_dtmf_str2setting(const char * value)
 {
-    return str2enum(value, dtmf_values, ITEMS_OF(dtmf_values));
+	return str2enum(value, dtmf_values, ITEMS_OF(dtmf_values));
 }
 
 EXPORT_DEF const char * dc_dtmf_setting2str(dc_dtmf_setting_t dtmf)
diff --git a/helpers.c b/helpers.c
index 163fb7a..d5948c2 100644
--- a/helpers.c
+++ b/helpers.c
@@ -1,9 +1,9 @@
-/* 
+/*
    Copyright (C) 2009 - 2010
-   
+
    Artem Makhutov <artem@makhutov.org>
    http://www.makhutov.org
-   
+
    Dmitry Vagin <dmitry2004@yandex.ru>
 
    bg <bg_one@mail.ru>
diff --git a/manager.c b/manager.c
index 0f9a0ca..f30ec55 100644
--- a/manager.c
+++ b/manager.c
@@ -3,12 +3,12 @@
 #endif /* HAVE_CONFIG_H */
 
 #ifdef BUILD_MANAGER /* no manager, no copyright */
-/* 
+/*
    Copyright (C) 2009 - 2010
-   
+
    Artem Makhutov <artem@makhutov.org>
    http://www.makhutov.org
-   
+
    Dmitry Vagin <dmitry2004@yandex.ru>
 
    bg <bg_one@mail.ru>
@@ -20,6 +20,8 @@
 #include <asterisk/strings.h>			/* ast_strlen_zero() */
 #include <asterisk/callerid.h>			/* ast_describe_caller_presentation */
 
+#include "ast_compat.h"				/* asterisk compatibility fixes */
+
 #include "manager.h"
 #include "chan_dongle.h"			/* devices */
 #include "helpers.h"				/* ITEMS_OF() send_ccwa_set() send_reset() send_sms() send_ussd() */
@@ -118,7 +120,7 @@ static int manager_show_devices (struct mansession* s, const struct message* m)
 	astman_append (s, "Event: DongleShowDevicesComplete\r\n");
 	if(!ast_strlen_zero (id))
 		astman_append (s, "ActionID: %s\r\n", id);
-	astman_append (s, 
+	astman_append (s,
 		"EventList: Complete\r\n"
 		"ListItems: %zu\r\n"
 		"\r\n",
@@ -176,7 +178,7 @@ static int manager_send_sms (struct mansession* s, const struct message* m)
 	const char*	msg;
 	int		status;
 	void * msgid;
-	
+
 	if (ast_strlen_zero (device))
 	{
 		astman_send_error (s, m, "Device not specified");
@@ -218,7 +220,7 @@ static int manager_send_pdu (struct mansession* s, const struct message* m)
 	const char*	msg;
 	int		status;
 	void * msgid;
-	
+
 	if (ast_strlen_zero (device))
 	{
 		astman_send_error (s, m, "Device not specified");
@@ -342,11 +344,11 @@ static char * espace_newlines(const char * text)
 				escaped[j++] = 'n';
 			} else {
 				escaped[j++] = text[i];
-			}	
+			}
 		}
 		escaped[j] = 0;
 	}
-	
+
 	return escaped;
 }
 
@@ -605,13 +607,13 @@ static const struct dongle_manager
 	const char*	name;
 	const char*	brief;
 	const char*	desc;
-} dcm[] = 
+} dcm[] =
 {
 	{
-	manager_show_devices, 
+	manager_show_devices,
 	EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING,
-	"DongleShowDevices", 
-	"List Dongle devices", 
+	"DongleShowDevices",
+	"List Dongle devices",
 	"Description: Lists Dongle devices in text format with details on current status.\n\n"
 	"DongleShowDevicesComplete.\n"
 	"Variables:\n"
@@ -619,9 +621,9 @@ static const struct dongle_manager
 	"	Device:   <name>	Optional name of device.\n"
 	},
 	{
-	manager_send_ussd, 
+	manager_send_ussd,
 	EVENT_FLAG_CALL,
-	"DongleSendUSSD", 
+	"DongleSendUSSD",
 	"Send a ussd command to the dongle.",
 	"Description: Send a ussd message to a dongle.\n\n"
 	"Variables: (Names marked with * are required)\n"
@@ -630,10 +632,10 @@ static const struct dongle_manager
 	"	*USSD:    <code>	The ussd code that will be send to the device.\n"
 	 },
 	{
-	manager_send_sms, 
+	manager_send_sms,
 	EVENT_FLAG_CALL,
-	"DongleSendSMS", 
-	"Send a SMS message.", 
+	"DongleSendSMS",
+	"Send a SMS message.",
 	"Description: Send a SMS message from a dongle.\n\n"
 	"Variables: (Names marked with * are required)\n"
 	"	ActionID: <id>		Action ID for this transaction. Will be returned.\n"
@@ -642,10 +644,10 @@ static const struct dongle_manager
 	"	*Message: <message>	The SMS message that will be send.\n"
 	},
 	{
-	manager_send_pdu, 
+	manager_send_pdu,
 	EVENT_FLAG_CALL,
-	"DongleSendPDU", 
-	"Send a PDU of message.", 
+	"DongleSendPDU",
+	"Send a PDU of message.",
 	"Description: Send a PDU of message from a dongle.\n\n"
 	"Variables: (Names marked with * are required)\n"
 	"	ActionID: <id>		Action ID for this transaction. Will be returned.\n"
@@ -653,9 +655,9 @@ static const struct dongle_manager
 	"	*PDU:     <PDU>		The PDU of SMS.\n"
 	},
 	{
-	manager_ccwa_set, 
+	manager_ccwa_set,
 	EVENT_FLAG_CONFIG,
-	"DongleSetCCWA", 
+	"DongleSetCCWA",
 	"Enable/Disabled Call-Waiting on a dongle.",
 	"Description: Enable/Disabled Call-Waiting on a dongle.\n\n"
 	"Variables: (Names marked with * are required)\n"
@@ -666,8 +668,8 @@ static const struct dongle_manager
 	{
 	manager_reset,
 	EVENT_FLAG_SYSTEM | EVENT_FLAG_CONFIG,
-	"DongleReset", 
-	"Reset a dongle.", 
+	"DongleReset",
+	"Reset a dongle.",
 	"Description: Reset a dongle.\n\n"
 	"Variables: (Names marked with * are required)\n"
 	"	ActionID: <id>		Action ID for this transaction. Will be returned.\n"
@@ -676,8 +678,8 @@ static const struct dongle_manager
 	{
 	manager_restart,
 	EVENT_FLAG_SYSTEM | EVENT_FLAG_CONFIG,
-	"DongleRestart", 
-	"Restart a dongle.", 
+	"DongleRestart",
+	"Restart a dongle.",
 	"Description: Restart a dongle.\n\n"
 	"Variables: (Names marked with * are required)\n"
 	"	ActionID: <id>		Action ID for this transaction. Will be returned.\n"
@@ -687,8 +689,8 @@ static const struct dongle_manager
 	{
 	manager_stop,
 	EVENT_FLAG_SYSTEM | EVENT_FLAG_CONFIG,
-	"DongleStop", 
-	"Stop a dongle.", 
+	"DongleStop",
+	"Stop a dongle.",
 	"Description: Stop a dongle.\n\n"
 	"Variables: (Names marked with * are required)\n"
 	"	ActionID: <id>		Action ID for this transaction. Will be returned.\n"
@@ -698,8 +700,8 @@ static const struct dongle_manager
 	{
 	manager_start,
 	EVENT_FLAG_SYSTEM | EVENT_FLAG_CONFIG,
-	"DongleStart", 
-	"Start a dongle.", 
+	"DongleStart",
+	"Start a dongle.",
 	"Description: Start a dongle.\n\n"
 	"Variables: (Names marked with * are required)\n"
 	"	ActionID: <id>		Action ID for this transaction. Will be returned.\n"
@@ -708,8 +710,8 @@ static const struct dongle_manager
 	{
 	manager_remove,
 	EVENT_FLAG_SYSTEM | EVENT_FLAG_CONFIG,
-	"DongleRemove", 
-	"Remove a dongle.", 
+	"DongleRemove",
+	"Remove a dongle.",
 	"Description: Remove a dongle.\n\n"
 	"Variables: (Names marked with * are required)\n"
 	"	ActionID: <id>		Action ID for this transaction. Will be returned.\n"
@@ -719,8 +721,8 @@ static const struct dongle_manager
 	{
 	manager_reload,
 	EVENT_FLAG_SYSTEM | EVENT_FLAG_CONFIG,
-	"DongleReload", 
-	"Reload a module configuration.", 
+	"DongleReload",
+	"Reload a module configuration.",
 	"Description: Reload the module configuration.\n\n"
 	"Variables: (Names marked with * are required)\n"
 	"	ActionID: <id>		Action ID for this transaction. Will be returned.\n"
@@ -733,7 +735,7 @@ EXPORT_DEF void manager_register()
 	unsigned i;
 #if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
 	struct ast_module* module = self_module();
-#endif
+#endif /* ^13+ */
 
 	for(i = 0; i < ITEMS_OF(dcm); i++)
 	{
@@ -742,9 +744,9 @@ EXPORT_DEF void manager_register()
 			module, dcm[i].brief, dcm[i].desc);
 #elif ASTERISK_VERSION_NUM >= 110000 /* 11+ */
 		ast_manager_register2 (dcm[i].name, dcm[i].authority, dcm[i].func, NULL, dcm[i].brief, dcm[i].desc);
-#else
+#else /* 11- */
 		ast_manager_register2 (dcm[i].name, dcm[i].authority, dcm[i].func, dcm[i].brief, dcm[i].desc);
-#endif
+#endif /* ^11- */
 	}
 }
 
diff --git a/mixbuffer.c b/mixbuffer.c
index ef97c7c..b5898a9 100644
--- a/mixbuffer.c
+++ b/mixbuffer.c
@@ -47,7 +47,7 @@ static inline size_t mixb_mix_write(struct mixbuffer * mb, struct mixstream * st
 	/* save global state */
 	size_t save_write = mb->rb.write;
 	size_t save_used = mb->rb.used;
-	
+
 	/* load local state */
 	mb->rb.write = stream->write;
 	mb->rb.used = stream->used;
diff --git a/pdiscovery.c b/pdiscovery.c
index f5576e8..0ac2877 100644
--- a/pdiscovery.c
+++ b/pdiscovery.c
@@ -1,4 +1,4 @@
-/*1
+/*
    Copyright (C) 2011 bg <bg_one@mail.ru>
 */
 #ifdef HAVE_CONFIG_H
@@ -20,7 +20,7 @@
 #include "manager.h"			/* manager_event_message_raw() */
 
 /*
-static const char sys_bus_usb_drivers_usb[] = "/sys/bus/usb/drivers/usb"; 
+static const char sys_bus_usb_drivers_usb[] = "/sys/bus/usb/drivers/usb";
 */
 static const char sys_bus_usb_devices[] = "/sys/bus/usb/devices";
 
@@ -94,7 +94,7 @@ static int ports_copy(struct pdiscovery_ports * dst, const struct pdiscovery_por
 			if(dst->ports[i] == NULL)
 				return 0;
 		}
-	return i;	
+	return i;
 }
 
 #/* */
@@ -114,12 +114,12 @@ static void info_free(struct pdiscovery_result * res)
 	if(res->imsi) {
 		ast_free(res->imsi);
 		res->imsi = NULL;
-	}	
+	}
 
 	if(res->imei) {
 		ast_free(res->imei);
 		res->imei = NULL;
-	}		
+	}
 }
 
 #/* */
@@ -152,7 +152,7 @@ static void cache_item_update(struct pdiscovery_cache_item * item, const struct
 {
 	info_free(&item->res);
 	info_copy(&item->res, res);
-	
+
 	item->status = status;
 
 	item->validtill = ast_tvnow();
@@ -171,7 +171,7 @@ static struct pdiscovery_cache_item * cache_item_create(const struct pdiscovery_
 			item = NULL;
 		}
 	}
-	
+
 	return item;
 }
 
@@ -517,11 +517,8 @@ static int pdiscovery_handle_response(const struct pdiscovery_request * req, con
 		len--;
 		if(iovcnt == 2) {
 			str = alloca(len + 1);
-			if(!str) {
-				return 1;
-			memcpy(str                 , iov[0].iov_base, iov[0].iov_len);
+			memcpy(str, iov[0].iov_base, iov[0].iov_len);
 			memcpy(str + iov[0].iov_len, iov[1].iov_base, iov[1].iov_len);
-			}
 		} else {
 			str = iov[0].iov_base;
 		}
@@ -606,7 +603,7 @@ static int pdiscovery_get_info(const char * port, const struct pdiscovery_reques
 		unsigned want_imei = req->imei && res->imei == NULL;		// 1 && 0
 		unsigned want_imsi = req->imsi && res->imsi == NULL;		// 1 && 1
 		unsigned cmd = want_map[want_imei][want_imsi];
-		
+
 		/* clean queue first ? */
 		fail = pdiscovery_do_cmd(req, fd, port, cmds[cmd].cmd, cmds[cmd].length, res);
 		closetty(fd, &lock_file);
@@ -627,7 +624,7 @@ static int pdiscovery_get_info_cached(const char * port, const struct pdiscovery
 	} else {
 		ast_debug(4, "[%s discovery] %s use cached IMEI %s IMSI %s failed %d\n", req->name, port, S_OR(res->imei, ""), S_OR(res->imsi, ""), fail);
 	}
-		
+
 	return fail;
 }
 
@@ -689,11 +686,11 @@ static int pdiscovery_check_device(const char * name, int len, const char * subd
 
 	device = pdiscovery_lookup_ids(req->name, name2, len2);
 	if(device) {
-//		ast_debug(4, "[%s discovery] should ports <-> interfaces map for %04x:%04x modem=%02x voice=%02x data=%02x\n", 
-		ast_debug(4, "[%s discovery] should ports <-> interfaces map for %04x:%04x voice=%02x data=%02x\n", 
+//		ast_debug(4, "[%s discovery] should ports <-> interfaces map for %04x:%04x modem=%02x voice=%02x data=%02x\n",
+		ast_debug(4, "[%s discovery] should ports <-> interfaces map for %04x:%04x voice=%02x data=%02x\n",
 			req->name,
-			device->vendor_id, 
-			device->product_id, 
+			device->vendor_id,
+			device->product_id,
 //			device->interfaces[INTERFACE_TYPE_COM],
 			device->interfaces[INTERFACE_TYPE_VOICE],
 			device->interfaces[INTERFACE_TYPE_DATA]
@@ -750,7 +747,7 @@ EXPORT_DEF int pdiscovery_lookup(const char * devname, const char * imei, const
 	int found;
 	struct pdiscovery_result res;
 	const struct pdiscovery_request req = {
-		devname, 
+		devname,
 		((imei && imei[0]) ? imei : NULL),
 		((imsi && imsi[0]) ? imsi : NULL),
 		};
@@ -771,9 +768,9 @@ EXPORT_DEF const struct pdiscovery_result * pdiscovery_list_begin(const struct p
 	const struct pdiscovery_cache_item * item;
 	struct pdiscovery_result res;
 	const struct pdiscovery_request req = {
-		"list", 
-		"ANY", 
-		"ANY", 
+		"list",
+		"ANY",
+		"ANY",
 		};
 
 	memset(&res, 0, sizeof(res));
diff --git a/pdu.c b/pdu.c
index e0bdab7..be840e0 100644
--- a/pdu.c
+++ b/pdu.c
@@ -406,7 +406,7 @@ static int pdu_parse_byte(char ** digits2hex, size_t * length)
 }
 
 /*!
- * \brief Store number in PDU 
+ * \brief Store number in PDU
  * \param buffer -- pointer to place where number will be stored, CALLER MUST be provide length + 2 bytes of buffer
  * \param number -- phone number w/o leading '+'
  * \param length -- length of number
@@ -431,10 +431,10 @@ static int pdu_store_number(char* buffer, const char* number, unsigned length)
 }
 
 /*
-failed parse 07 91  97 62 02 00 01 F9  44  14 D0 F7 FB DD D5 2E 9F C3 E6 B7 1B  0008117050815073618C0500037A020100680066006C0067006800200066006800670020006800640066006A006C006700680066006400680067000A002F00200415043604350434043D04350432043D044B04390020043B04380447043D044B043900200433043E0440043E0441043A043E043F003A0020002A003500300035002300360023002000200028003300200440002F0441 
+failed parse 07 91  97 62 02 00 01 F9  44  14 D0 F7 FB DD D5 2E 9F C3 E6 B7 1B  0008117050815073618C0500037A020100680066006C0067006800200066006800670020006800640066006A006C006700680066006400680067000A002F00200415043604350434043D04350432043D044B04390020043B04380447043D044B043900200433043E0440043E0441043A043E043F003A0020002A003500300035002300360023002000200028003300200440002F0441
 
                                               ^^  not a international format
-failed parse 07 91  97 30 07 11 11 F1  04  14 D0 D9B09B5CC637DFEE721E0008117020616444617E041A043E04340020043F043E04340442043204350440043604340435043D0438044F003A00200036003900320037002E0020041D0438043A043E043C04430020043D043500200441043E043E043104490430043904420435002C002004320432043504340438044204350020043D0430002004410430043904420435002E 
+failed parse 07 91  97 30 07 11 11 F1  04  14 D0 D9B09B5CC637DFEE721E0008117020616444617E041A043E04340020043F043E04340442043204350440043604340435043D0438044F003A00200036003900320037002E0020041D0438043A043E043C04430020043D043500200441043E043E043104490430043904420435002C002004320432043504340438044204350020043D0430002004410430043904420435002E
                                               ^^  not a international format
 */
 #/* reverse of pdu_store_number() */
@@ -673,170 +673,170 @@ EXPORT_DEF const char * pdu_parse(char ** pdu, size_t tpdu_length, char * oa, si
 	int field_len = pdu_parse_sca(pdu, &pdu_length);
 	if(field_len > 0)
 	{
-	    if(tpdu_length * 2 == pdu_length)
-	    {
-		int pdu_type = pdu_parse_byte(pdu, &pdu_length);
-		if(pdu_type >= 0)
+		if(tpdu_length * 2 == pdu_length)
 		{
-			/* TODO: also handle PDUTYPE_MTI_SMS_SUBMIT_REPORT and PDUTYPE_MTI_SMS_STATUS_REPORT */
-			if(PDUTYPE_MTI(pdu_type) == PDUTYPE_MTI_SMS_DELIVER)
+			int pdu_type = pdu_parse_byte(pdu, &pdu_length);
+			if(pdu_type >= 0)
 			{
-				int oa_digits = pdu_parse_byte(pdu, &pdu_length);
-				if(oa_digits > 0)
+				/* TODO: also handle PDUTYPE_MTI_SMS_SUBMIT_REPORT and PDUTYPE_MTI_SMS_STATUS_REPORT */
+				if(PDUTYPE_MTI(pdu_type) == PDUTYPE_MTI_SMS_DELIVER)
 				{
-					int oa_toa;
-					field_len = pdu_parse_number(pdu, &pdu_length, oa_digits, &oa_toa, oa, oa_len);
-					if(field_len > 0)
+					int oa_digits = pdu_parse_byte(pdu, &pdu_length);
+					if(oa_digits > 0)
 					{
-						int pid = pdu_parse_byte(pdu, &pdu_length);
-						*oa_enc = STR_ENCODING_7BIT;
-						if(pid >= 0)
+						int oa_toa;
+						field_len = pdu_parse_number(pdu, &pdu_length, oa_digits, &oa_toa, oa, oa_len);
+						if(field_len > 0)
 						{
-						   /* TODO: support other types of messages */
-						   if(pid == PDU_PID_SMS)
-						   {
-							int dcs = pdu_parse_byte(pdu, &pdu_length);
-							if(dcs >= 0)
+							int pid = pdu_parse_byte(pdu, &pdu_length);
+							*oa_enc = STR_ENCODING_7BIT;
+							if(pid >= 0)
 							{
-							    // TODO: support compression
-							    if( PDU_DCS_76(dcs) == PDU_DCS_76_00
-							    		&&
-							    	PDU_DCS_COMPRESSION(dcs) == PDU_DCS_NOT_COMPESSED
-							    		&&
-							    		(
-							    		PDU_DCS_ALPABET(dcs) == PDU_DCS_ALPABET_7BIT
-							    			||
-							    		PDU_DCS_ALPABET(dcs) == PDU_DCS_ALPABET_8BIT
-							    			||
-							    		PDU_DCS_ALPABET(dcs) == PDU_DCS_ALPABET_UCS2
-							    		)
-							    	)
-							    {
-								int ts = pdu_parse_timestamp(pdu, &pdu_length);
-								*msg_enc = pdu_dcs_alpabet2encoding(PDU_DCS_ALPABET(dcs));
-								if(ts >= 0)
+								/* TODO: support other types of messages */
+								if(pid == PDU_PID_SMS)
 								{
-									int udl = pdu_parse_byte(pdu, &pdu_length);
-									if(udl >= 0)
+									int dcs = pdu_parse_byte(pdu, &pdu_length);
+									if(dcs >= 0)
 									{
-										/* calculate number of octets in UD */
-										if(PDU_DCS_ALPABET(dcs) == PDU_DCS_ALPABET_7BIT)
-											udl = ((udl + 1) * 7) >> 3;
-										if((size_t)udl * 2 == pdu_length)
+										// TODO: support compression
+										if( PDU_DCS_76(dcs) == PDU_DCS_76_00
+												&&
+												PDU_DCS_COMPRESSION(dcs) == PDU_DCS_NOT_COMPESSED
+												&&
+												(
+												 PDU_DCS_ALPABET(dcs) == PDU_DCS_ALPABET_7BIT
+												 ||
+												 PDU_DCS_ALPABET(dcs) == PDU_DCS_ALPABET_8BIT
+												 ||
+												 PDU_DCS_ALPABET(dcs) == PDU_DCS_ALPABET_UCS2
+												)
+										  )
 										{
-											if(PDUTYPE_UDHI(pdu_type) == PDUTYPE_UDHI_HAS_HEADER)
+											int ts = pdu_parse_timestamp(pdu, &pdu_length);
+											*msg_enc = pdu_dcs_alpabet2encoding(PDU_DCS_ALPABET(dcs));
+											if(ts >= 0)
 											{
-												/* TODO: implement header parse */
-												int udhl = pdu_parse_byte(pdu, &pdu_length);
-												if(udhl >= 0)
+												int udl = pdu_parse_byte(pdu, &pdu_length);
+												if(udl >= 0)
 												{
-													/* NOTE: UDHL count octets no need calculation */
-													if(pdu_length >= (size_t)(udhl * 2))
+													/* calculate number of octets in UD */
+													if(PDU_DCS_ALPABET(dcs) == PDU_DCS_ALPABET_7BIT)
+														udl = ((udl + 1) * 7) >> 3;
+													if((size_t)udl * 2 == pdu_length)
 													{
-														/* skip UDH */
-														*pdu += udhl * 2;
-														pdu_length -= udhl * 2;
+														if(PDUTYPE_UDHI(pdu_type) == PDUTYPE_UDHI_HAS_HEADER)
+														{
+															/* TODO: implement header parse */
+															int udhl = pdu_parse_byte(pdu, &pdu_length);
+															if(udhl >= 0)
+															{
+																/* NOTE: UDHL count octets no need calculation */
+																if(pdu_length >= (size_t)(udhl * 2))
+																{
+																	/* skip UDH */
+																	*pdu += udhl * 2;
+																	pdu_length -= udhl * 2;
+																}
+																else
+																{
+																	err = "Invalid UDH";
+																}
+															}
+															else
+															{
+																err = "Can't parse UDHL";
+															}
+														}
+														/* save message */
+														*msg = *pdu;
 													}
 													else
 													{
-														err = "Invalid UDH";
+														*pdu -= 2;
+														err = "UDL not match with UD length";
 													}
 												}
 												else
 												{
-													err = "Can't parse UDHL";
+													err = "Can't parse UDL";
 												}
 											}
-											/* save message */
-											*msg = *pdu;
+											else
+											{
+												err = "Can't parse Timestamp";
+											}
 										}
 										else
 										{
 											*pdu -= 2;
-											err = "UDL not match with UD length";
+											err = "Unsupported DCS value";
 										}
 									}
 									else
 									{
-										err = "Can't parse UDL";
+										err = "Can't parse DSC";
 									}
 								}
 								else
 								{
-									err = "Can't parse Timestamp";
+									err = "Unhandled PID value, only SMS supported";
 								}
-							    }
-							    else
-							    {
-								*pdu -= 2;
-								err = "Unsupported DCS value";
-							    }
 							}
 							else
 							{
-								err = "Can't parse DSC";
+								err = "Can't parse PID";
 							}
-						    }
-						    else
-						    {
-						    	err = "Unhandled PID value, only SMS supported";
-						    }
 						}
 						else
 						{
-							err = "Can't parse PID";
+							err = "Can't parse OA";
 						}
 					}
 					else
 					{
-						err = "Can't parse OA";
+						err = "Can't parse length of OA";
 					}
 				}
-				else
+				else if(PDUTYPE_MTI(pdu_type) == PDUTYPE_MTI_SMS_STATUS_REPORT)
 				{
-					err = "Can't parse length of OA";
-				}
-			}
-			else if(PDUTYPE_MTI(pdu_type) == PDUTYPE_MTI_SMS_STATUS_REPORT)
-			{
-				int reference = pdu_parse_byte(pdu, &pdu_length);
-				/* Skip over 8 bytes TP-DA */
-				if (reference >= 0 && pdu_length >= 8) {
-					(*pdu) += 8;
-					pdu_length -= 8;
-					/* Skip over 7 bytes timestamp TP-SCTS */
-					if (pdu_parse_timestamp(pdu, &pdu_length) >= 0 &&
-					    /* Skip over 7 bytes timestamp TP-DT */
-					    pdu_parse_timestamp(pdu, &pdu_length) >= 0) {
-						int tp_status = pdu_parse_byte(pdu, &pdu_length);
-						if ((tp_status & 0xf) == 0) {
-							err = (void*)0x1; /* HACK! */
-							*msg = (char*)(ssize_t)reference; /* HACK! */
+					int reference = pdu_parse_byte(pdu, &pdu_length);
+					/* Skip over 8 bytes TP-DA */
+					if (reference >= 0 && pdu_length >= 8) {
+						(*pdu) += 8;
+						pdu_length -= 8;
+						/* Skip over 7 bytes timestamp TP-SCTS */
+						if (pdu_parse_timestamp(pdu, &pdu_length) >= 0 &&
+								/* Skip over 7 bytes timestamp TP-DT */
+								pdu_parse_timestamp(pdu, &pdu_length) >= 0) {
+							int tp_status = pdu_parse_byte(pdu, &pdu_length);
+							if ((tp_status & 0xf) == 0) {
+								err = (void*)0x1; /* HACK! */
+								*msg = (char*)(ssize_t)reference; /* HACK! */
+							} else {
+								err = "Good report, but delivery failed";
+							}
 						} else {
-							err = "Good report, but delivery failed";
+							err = "FIXME error 1";
 						}
 					} else {
-						err = "FIXME error 1";
+						err = "FIXME error 2";
 					}
-				} else {
-					err = "FIXME error 2";
+				}
+				else
+				{
+					*pdu -= 2;
+					err = "Unhandled PDU Type MTI only SMS-DELIVER/SMS-STATUS-REPORT supported";
 				}
 			}
 			else
 			{
-				*pdu -= 2;
-				err = "Unhandled PDU Type MTI only SMS-DELIVER/SMS-STATUS-REPORT supported";
+				err = "Can't parse PDU Type";
 			}
 		}
 		else
 		{
-			err = "Can't parse PDU Type";
+			err = "TPDU length not matched with actual length";
 		}
-	    }
-	    else
-	    {
-		err = "TPDU length not matched with actual length";
-	    }
 	}
 	else
 	{
diff --git a/ringbuffer.c b/ringbuffer.c
index 655be76..08429ab 100644
--- a/ringbuffer.c
+++ b/ringbuffer.c
@@ -1,9 +1,9 @@
-/* 
+/*
    Copyright (C) 2009 - 2010
-   
+
    Artem Makhutov <artem@makhutov.org>
    http://www.makhutov.org
-   
+
    Dmitry Vagin <dmitry2004@yandex.ru>
 */
 #ifdef HAVE_CONFIG_H
@@ -35,7 +35,7 @@ EXPORT_DEF int rb_memcmp (const struct ringbuffer* rb, const char* mem, size_t l
 				}
 			}
 		}
-		else 
+		else
 		{
 			if (memcmp (rb->buffer + rb->read, mem, len) == 0)
 			{
@@ -119,7 +119,7 @@ EXPORT_DEF int rb_read_until_char_iov (const struct ringbuffer* rb, struct iovec
 				iov[1].iov_len = 0;
 				return 1;
 			}
-		
+
 			if ((p = memchr (rb->buffer, c, rb->used - iov[0].iov_len)) != NULL)
 			{
 				iov[1].iov_base = rb->buffer;
@@ -127,7 +127,7 @@ EXPORT_DEF int rb_read_until_char_iov (const struct ringbuffer* rb, struct iovec
 				return 2;
 			}
 		}
-		else 
+		else
 		{
 			iov[0].iov_base = rb->buffer + rb->read;
 			iov[0].iov_len  = rb->used;
@@ -205,14 +205,14 @@ EXPORT_DEF int rb_read_until_mem_iov (const struct ringbuffer* rb, struct iovec
 						iov[1].iov_len = 0;
 						return 1;
 					}
-				
+
 					iov[1].iov_base = rb->buffer;
 					iov[1].iov_len = p - rb->buffer;
 					return 2;
 				}
 			}
 		}
-		else 
+		else
 		{
 			iov[0].iov_base = rb->buffer + rb->read;
 			iov[0].iov_len  = rb->used;
diff --git a/ringbuffer.h b/ringbuffer.h
index 7bc0766..8e51c3b 100644
--- a/ringbuffer.h
+++ b/ringbuffer.h
@@ -1,9 +1,9 @@
-/* 
+/*
    Copyright (C) 2009 - 2010
-   
+
    Artem Makhutov <artem@makhutov.org>
    http://www.makhutov.org
-   
+
    Dmitry Vagin <dmitry2004@yandex.ru>
 */
 
diff --git a/test/parse.c b/test/parse.c
index 43d58cf..37d5010 100644
--- a/test/parse.c
+++ b/test/parse.c
@@ -107,15 +107,11 @@ void test_parse_creg()
 		fprintf(stderr, "%s(\"%s\")...", "at_parse_creg", input);
 		result.res = at_parse_creg(input, strlen(input), &result.gsm_reg, &result.gsm_reg_status, &result.lac, &result.ci);
 		if(result.res == cases[idx].result.res
-			&&
-		   result.gsm_reg == cases[idx].result.gsm_reg
-			&&
-		   result.gsm_reg_status == cases[idx].result.gsm_reg_status
-			&&
-		   strcmp(result.lac, cases[idx].result.lac) == 0
-			&&
-		   strcmp(result.ci, cases[idx].result.ci) == 0
-			) {
+			&& result.gsm_reg == cases[idx].result.gsm_reg
+			&& result.gsm_reg_status == cases[idx].result.gsm_reg_status
+			&& strcmp(result.lac, cases[idx].result.lac) == 0
+			&& strcmp(result.ci, cases[idx].result.ci) == 0)
+		{
 			msg = "OK";
 			ok++;
 		} else {
@@ -230,18 +226,13 @@ void test_parse_cmgr()
 		result.str = input = strdup(cases[idx].input);
 		fprintf(stderr, "%s(\"%s\")...", "at_parse_cmgr", input);
 		result.res = at_parse_cmgr(&result.str, strlen(result.str), result.oa, sizeof(oa), &result.oa_enc, &result.msg, &result.msg_enc);
-		if( ((result.res == NULL && result.res == cases[idx].result.res) || strcmp(result.res, cases[idx].result.res) == 0)
-			&&
-		   strcmp(result.str, cases[idx].result.str) == 0
-			&&
-		   strcmp(result.oa, cases[idx].result.oa) == 0
-			&&
-		   result.oa_enc == cases[idx].result.oa_enc
-			&&
-		   strcmp(result.msg, cases[idx].result.msg) == 0
-			&&
-		   result.msg_enc == cases[idx].result.msg_enc
-			) {
+		if(((result.res == NULL && result.res == cases[idx].result.res) || strcmp(result.res, cases[idx].result.res) == 0)
+			&& strcmp(result.str, cases[idx].result.str) == 0
+			&& strcmp(result.oa, cases[idx].result.oa) == 0
+			&& result.oa_enc == cases[idx].result.oa_enc
+			&& strcmp(result.msg, cases[idx].result.msg) == 0
+			&& result.msg_enc == cases[idx].result.msg_enc)
+		{
 			msg = "OK";
 			ok++;
 		} else {
@@ -281,13 +272,10 @@ void test_parse_cusd()
 		fprintf(stderr, "%s(\"%s\")...", "at_parse_cusd", input);
 		result.res = at_parse_cusd(input, &result.type, &result.cusd, &result.dcs);
 		if(result.res == cases[idx].result.res
-			&&
-		   result.type == cases[idx].result.type
-			&&
-		   result.dcs == cases[idx].result.dcs
-			&&
-		   strcmp(result.cusd, cases[idx].result.cusd) == 0
-			) {
+			&& result.type == cases[idx].result.type
+			&& result.dcs == cases[idx].result.dcs
+			&& strcmp(result.cusd, cases[idx].result.cusd) == 0)
+		{
 			msg = "OK";
 			ok++;
 		} else {
@@ -358,21 +346,14 @@ void test_parse_clcc()
 		fprintf(stderr, "%s(\"%s\")...", "at_parse_clcc", input);
 		result.res = at_parse_clcc(input, &result.index, &result.dir, &result.stat, &result.mode, &result.mpty, &result.number, &result.toa);
 		if(result.res == cases[idx].result.res
-			&&
-		   result.index == cases[idx].result.index
-			&&
-		   result.dir == cases[idx].result.dir
-			&&
-		   result.stat == cases[idx].result.stat
-			&&
-		   result.mode == cases[idx].result.mode
-			&&
-		   result.mpty == cases[idx].result.mpty
-			&&
-		   strcmp(result.number, cases[idx].result.number) == 0
-			&&
-		   result.toa == cases[idx].result.toa
-			) {
+			&& result.index == cases[idx].result.index
+			&& result.dir == cases[idx].result.dir
+			&& result.stat == cases[idx].result.stat
+			&& result.mode == cases[idx].result.mode
+			&& result.mpty == cases[idx].result.mpty
+			&& strcmp(result.number, cases[idx].result.number) == 0
+			&& result.toa == cases[idx].result.toa)
+		{
 			msg = "OK";
 			ok++;
 		} else {
@@ -409,4 +390,4 @@ int main()
 	
 	fprintf(stderr, "done %d tests: %d OK %d FAILS\n", ok + faults, ok, faults);
 	return 0;
-}
\ No newline at end of file
+}

From 58014345d15f60b746a6ce62cc5dc8b83762da3b Mon Sep 17 00:00:00 2001
From: yylyyl <yangyiliang@gmail.com>
Date: Sat, 19 Sep 2015 20:11:09 +0800
Subject: [PATCH 10/15] Applied chan-dongle-alphanumeric-pdu.patch.

USSD for E261 works now.

Source: https://code.google.com/p/asterisk-chan-dongle/issues/detail?id=17
---
 README.txt    |  1 +
 at_response.c |  1 +
 pdu.c         | 15 ++++++++++++++-
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/README.txt b/README.txt
index d9a8c8b..4a26704 100644
--- a/README.txt
+++ b/README.txt
@@ -16,6 +16,7 @@ This channel driver should work with the folowing UMTS cards:
 * Huawei E169 / K3520
 * Huawei E155X
 * Huawei E175X
+* Huawei E261
 * Huawei K3765
 
 Check complete list in:
diff --git a/at_response.c b/at_response.c
index 83e800a..3ac5411 100644
--- a/at_response.c
+++ b/at_response.c
@@ -1616,6 +1616,7 @@ static int at_response_cgmm (struct pvt* pvt, const char* str)
 		"E153",
 		"E156B",
 		"E1752",
+		"E261"
 	};
 
 	ast_copy_string (pvt->model, str, sizeof (pvt->model));
diff --git a/pdu.c b/pdu.c
index be840e0..d2c8403 100644
--- a/pdu.c
+++ b/pdu.c
@@ -182,6 +182,8 @@
 */
 
 #define NUMBER_TYPE_INTERNATIONAL		0x91
+#define NUMBER_TYPE_NATIONAL			0xC8
+#define NUMBER_TYPE_ALPHANUMERIC		0xD0
 
 /* Message Type Indicator Parameter */
 #define PDUTYPE_MTI_SHIFT			0
@@ -229,6 +231,7 @@
 
 #define PDU_PID_SMS				0x00		/* bit5 No interworking, but SME-to-SME protocol = SMS */
 #define PDU_PID_EMAIL				0x32		/* bit5 Telematic interworking, bits 4..0 0x 12  = email */
+#define PDU_PID_SMS_REPLACE_MASK		0x40		/* bit7 Replace Short Message function activated (TP-PID = 0x41 to 0x47) */
 
 /* DCS */
 /*   bits 1..0 Class */
@@ -454,7 +457,15 @@ static int pdu_parse_number(char ** pdu, size_t * pdu_length, unsigned digits, i
 		{
 			char digit;
 			if(*toa == NUMBER_TYPE_INTERNATIONAL)
+			{
 				*number++ = '+';
+			}
+			else if(*toa == NUMBER_TYPE_ALPHANUMERIC)
+			{
+				for(; syms > 0; syms--, *pdu += 1, *pdu_length -= 1)
+					*number++ = pdu[0][0];
+				return *pdu - begin;
+			}
 			for(; syms > 0; syms -= 2, *pdu += 2, *pdu_length -= 2)
 			{
 				digit = pdu_code2digit(pdu[0][1]);
@@ -690,10 +701,12 @@ EXPORT_DEF const char * pdu_parse(char ** pdu, size_t tpdu_length, char * oa, si
 						{
 							int pid = pdu_parse_byte(pdu, &pdu_length);
 							*oa_enc = STR_ENCODING_7BIT;
+							if(oa_toa == NUMBER_TYPE_ALPHANUMERIC)
+								*oa_enc = STR_ENCODING_7BIT_HEX;
 							if(pid >= 0)
 							{
 								/* TODO: support other types of messages */
-								if(pid == PDU_PID_SMS)
+								if( (pid == PDU_PID_SMS) || (pid & PDU_PID_SMS_REPLACE_MASK) )
 								{
 									int dcs = pdu_parse_byte(pdu, &pdu_length);
 									if(dcs >= 0)

From 1cf0f4bcf65fc6ee8e2a9c0a0fb0d532ce913a27 Mon Sep 17 00:00:00 2001
From: Walter Doekes <walter+github@wjd.nu>
Date: Sun, 20 Sep 2015 11:48:50 +0200
Subject: [PATCH 11/15] Move ASTERISK_VERSION_NUM setting to ./configure
 invocation:

Now do:

    ./configure --with-astversion=110102

if you have Asterisk version 11.1.2.
---
 configure.in | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/configure.in b/configure.in
index 9edd7a8..0a0c861 100644
--- a/configure.in
+++ b/configure.in
@@ -23,6 +23,15 @@ AC_ARG_WITH(
 	[ with_asterisk="../include /usr/include /usr/local/include /opt/local/include" ]
 )
 
+dnl  Required: asterisk version
+AC_ARG_WITH(
+	[astversion],
+	AS_HELP_STRING([--with-astversion=MMmmuu], [set asterisk version to 10813 for version 1.8.13]),
+	[ if ! test "$((with_astversion + 0))" -eq "$with_astversion" ; then AC_MSG_ERROR([Invalid --with-astversion=MMmmuu value]); fi ],
+	[ AC_MSG_ERROR([Please set --with-astversion=MMmmuu (major.minor.micro)]) ]
+)
+CPPFLAGS="$CPPFLAGS -DASTERISK_VERSION_NUM=$with_astversion"
+
 AC_ARG_ENABLE(
 	[debug], 
 	AS_HELP_STRING([--enable-debug], [enable code debugging]),

From 6e282785a7b9fc3b635d4d3425e31dc66c7fca01 Mon Sep 17 00:00:00 2001
From: Walter Doekes <walter+github@wjd.nu>
Date: Sun, 20 Sep 2015 12:08:57 +0200
Subject: [PATCH 12/15] Fix channel unlock issue in Asterisk >= 12.

Thanks @bg111 for the review.
---
 at_response.c | 8 ++++----
 channel.c     | 7 +++++++
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/at_response.c b/at_response.c
index 3ac5411..c47d0ba 100644
--- a/at_response.c
+++ b/at_response.c
@@ -868,10 +868,10 @@ static int start_pbx(struct pvt* pvt, const char * number, int call_idx, call_st
 // FIXME: not execute if channel_new() failed
 	CPVT_SET_FLAGS(cpvt, CALL_FLAG_NEED_HANGUP);
 
-	// ast_pbx_start() usually failed if asterisk.conf minmemfree set too low, try drop buffer cache sync && echo 3 > /proc/sys/vm/drop_caches
-#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
-	ast_channel_unlock(channel);
-#endif /* ^13+ */
+	/* ast_pbx_start() usually failed if asterisk.conf minmemfree
+	 * set too low, try drop buffer cache
+	 * sync && echo 3 >/proc/sys/vm/drop_caches
+	 */
 	if (ast_pbx_start (channel))
 	{
 		ast_channel_tech_pvt_set(channel, NULL);
diff --git a/channel.c b/channel.c
index a14bcca..a4aaf92 100644
--- a/channel.c
+++ b/channel.c
@@ -1296,6 +1296,13 @@ EXPORT_DEF struct ast_channel* new_channel(
 
 			ast_module_ref (self_module());
 
+#if ASTERISK_VERSION_NUM >= 120000 /* 12+ */
+			/* commit e2630fcd516b8f794bf342d9fd267b0c905e79ce
+			 * Date:   Wed Dec 18 19:28:05 2013 +0000a
+			 * ast_channel_alloc() returns allocated channels locked. */
+			ast_channel_unlock(channel);
+#endif /* ^12+ */
+
 			return channel;
 		}
 		cpvt_free(cpvt);

From 6dad1231763977b12db712943c02bcbe89c32a17 Mon Sep 17 00:00:00 2001
From: Walter Doekes <walter+github@wjd.nu>
Date: Sun, 20 Sep 2015 12:19:23 +0200
Subject: [PATCH 13/15] Clean up horrific ASTERISK_VERSION_NUM #if/#elif in
 channel_request.

---
 channel.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/channel.c b/channel.c
index a4aaf92..40dd629 100644
--- a/channel.c
+++ b/channel.c
@@ -151,23 +151,28 @@ static struct ast_channel * channel_request(
 
 #if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
 	if (ast_format_cap_iscompatible_format(cap, ast_format_slin) != AST_FORMAT_CMP_EQUAL)
-#elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
-	if (!ast_format_cap_iscompatible(cap, &chan_dongle_format))
-#else /* 10- */
-	oldformat = format;
-	format &= AST_FORMAT_SLINEAR;
-	if (!format)
-#endif /* ^10- */
 	{
-#if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
 		struct ast_str *codec_buf = ast_str_alloca(64);
 		ast_log(LOG_WARNING, "Asked to get a channel of unsupported format '%s'\n",
 				ast_format_cap_get_names(cap, &codec_buf));
+		*cause = AST_CAUSE_FACILITY_NOT_IMPLEMENTED;
+		return NULL;
+	}
 #elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
+	if (!ast_format_cap_iscompatible(cap, &chan_dongle_format))
+	{
 		char buf[255];
 		ast_log(LOG_WARNING, "Asked to get a channel of unsupported format '%s'\n",
 				ast_getformatname_multiple(buf, 255, cap));
-#elif ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
+		*cause = AST_CAUSE_FACILITY_NOT_IMPLEMENTED;
+		return NULL;
+	}
+#else /* 10- */
+	oldformat = format;
+	format &= AST_FORMAT_SLINEAR;
+	if (!format)
+	{
+#if ASTERISK_VERSION_NUM >= 10800 /* 1.8+ */
 		ast_log(LOG_WARNING, "Asked to get a channel of unsupported format '%s'\n",
 				ast_getformatname(oldformat));
 #else /* 1.8- */
@@ -177,6 +182,7 @@ static struct ast_channel * channel_request(
 		*cause = AST_CAUSE_FACILITY_NOT_IMPLEMENTED;
 		return NULL;
 	}
+#endif /* ^10- */
 
 	dest_dev = ast_strdupa (data);
 

From c5c0c5da56e55908395a1ba4f284e190a36184dc Mon Sep 17 00:00:00 2001
From: Walter Doekes <walter+github@wjd.nu>
Date: Sun, 20 Sep 2015 13:17:30 +0200
Subject: [PATCH 14/15] build: Properly force a recompile on config.h change.

Also move the ASTERISK_VERSION_NUM to config.h.
---
 Makefile.in  |  6 +++---
 config.h.in  | 48 ++++++++++++++++++++++++++++++------------------
 configure.in |  4 +++-
 stamp-h.in   |  1 +
 4 files changed, 37 insertions(+), 22 deletions(-)

diff --git a/Makefile.in b/Makefile.in
index 92674a8..1265182 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -61,7 +61,7 @@ $(PROJS): $(chan_dongles_so_OBJS) Makefile
 	$(CHMOD) 755 $@
 	mv $@ chan_dongle.so
 
-.c.o:
+.c.o: Makefile config.h
 	$(CC) $(CFLAGS) $(MAKE_DEPS) -o $@ -c $<
 
 tests: test/test1 test/parse
@@ -88,8 +88,8 @@ dist: $(SOURCES) $(HEADERS) $(EXTRA_DIST) $(BUILD_TOOLS)
 	tar czf $(DISTNAME).tgz $(DISTNAME) --exclude .svn -h
 	@$(RM) $(DISTNAME)
 
-${srcdir}/configure: configure.in
-	cd ${srcdir} && autoconf
+configure: configure.in
+	autoconf
 
 config.h: stamp-h
 stamp-h: config.h.in config.status
diff --git a/config.h.in b/config.h.in
index a977ab9..6ac3f32 100644
--- a/config.h.in
+++ b/config.h.in
@@ -1,5 +1,7 @@
-#ifndef CONFIG_H_INCLUDED
-#define CONFIG_H_INCLUDED
+/* config.h.in.  Generated from configure.in by autoheader.  */
+
+/* The Asterisk version as configured --with-astversion. */
+#undef ASTERISK_VERSION_NUM
 
 /* name of asterisk module */
 #undef AST_MODULE
@@ -10,12 +12,12 @@
 /* Build Manager extentions */
 #undef BUILD_MANAGER
 
+/* Define to 1 if you have HAVE_AST_CONTROL_SRCCHANGE in asterisk/frame.h */
+#undef HAVE_AST_CONTROL_SRCCHANGE
+
 /* Define to 1 if you have the <fcntl.h> header file. */
 #undef HAVE_FCNTL_H
 
-/* Define to 1 if you have the <iconv.h> header file. */
-#undef HAVE_ICONV_H
-
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
@@ -34,6 +36,9 @@
 /* Define to 1 if you have the `memset' function. */
 #undef HAVE_MEMSET
 
+/* Define to 1 if you have the `realpath' function. */
+#undef HAVE_REALPATH
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
@@ -46,9 +51,6 @@
 /* Define to 1 if you have the `strchr' function. */
 #undef HAVE_STRCHR
 
-/* Define to 1 if you have the `realpath' function. */
-#undef HAVE_REALPATH
-
 /* Define to 1 if you have the <strings.h> header file. */
 #undef HAVE_STRINGS_H
 
@@ -82,33 +84,45 @@
 /* Define to iconv_t if you has iconv_t in iconv.h */
 #undef ICONV_T
 
-/* Define to 1 if you have HAVE_AST_CONTROL_SRCCHANGE in asterisk/frame.h */
-#undef HAVE_AST_CONTROL_SRCCHANGE
+/* Define to the address where bug reports for this package should be sent */
+#undef MODULE_BUGREPORT
+
+/* Define to the home page for this package */
+#undef MODULE_URL
+
+/* Define to the version of this package */
+#undef MODULE_VERSION
+
+/* Name of package */
+#undef PACKAGE
 
 /* Define to the address where bug reports for this package should be sent. */
-#undef MODULE_BUGREPORT
+#undef PACKAGE_BUGREPORT
 
 /* Define to the full name of this package. */
-//#undef PACKAGE_NAME
+#undef PACKAGE_NAME
 
 /* Revision of package */
 #undef PACKAGE_REVISION
 
 /* Define to the full name and version of this package. */
-//#undef PACKAGE_STRING
+#undef PACKAGE_STRING
 
 /* Define to the one symbol short name of this package. */
-//#undef PACKAGE_TARNAME
+#undef PACKAGE_TARNAME
 
 /* Define to the home page for this package. */
-#undef MODULE_URL
+#undef PACKAGE_URL
 
 /* Define to the version of this package. */
-#undef MODULE_VERSION
+#undef PACKAGE_VERSION
 
 /* Define to 1 if you have the ANSI C header files. */
 #undef STDC_HEADERS
 
+/* Version number of package */
+#undef VERSION
+
 /* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
    <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
    #define below would cause a syntax error. */
@@ -135,5 +149,3 @@
 /* Define to the type of an unsigned integer type of width exactly 64 bits if
    such a type exists and the standard includes do not define it. */
 #undef uint64_t
-
-#endif /* CONFIG_H_INCLUDED */
diff --git a/configure.in b/configure.in
index 0a0c861..52befd6 100644
--- a/configure.in
+++ b/configure.in
@@ -7,6 +7,7 @@ AC_CANONICAL_TARGET
 AM_INIT_AUTOMAKE
 AC_CONFIG_HEADERS([config.h])
 AC_CONFIG_SRCDIR([chan_dongle.c])
+AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h])
 AC_CANONICAL_SYSTEM
 AC_CANONICAL_HOST
 
@@ -30,7 +31,8 @@ AC_ARG_WITH(
 	[ if ! test "$((with_astversion + 0))" -eq "$with_astversion" ; then AC_MSG_ERROR([Invalid --with-astversion=MMmmuu value]); fi ],
 	[ AC_MSG_ERROR([Please set --with-astversion=MMmmuu (major.minor.micro)]) ]
 )
-CPPFLAGS="$CPPFLAGS -DASTERISK_VERSION_NUM=$with_astversion"
+AC_DEFINE_UNQUOTED([ASTERISK_VERSION_NUM], [$with_astversion],
+		   [The Asterisk version as configured --with-astversion.])
 
 AC_ARG_ENABLE(
 	[debug], 
diff --git a/stamp-h.in b/stamp-h.in
index e69de29..9788f70 100644
--- a/stamp-h.in
+++ b/stamp-h.in
@@ -0,0 +1 @@
+timestamp

From c3490bbae8ba96f937ebd93d17155d8ad0766b48 Mon Sep 17 00:00:00 2001
From: Walter Doekes <walter+github@wjd.nu>
Date: Sun, 20 Sep 2015 13:47:50 +0200
Subject: [PATCH 15/15] Clean up format_cap_set stuff. Possibly fixing Local
 channel support.

---
 chan_dongle.c |  1 -
 chan_dongle.h |  1 -
 channel.c     | 26 +++++++++++++++++---------
 3 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/chan_dongle.c b/chan_dongle.c
index 01d17f7..ff87e32 100644
--- a/chan_dongle.c
+++ b/chan_dongle.c
@@ -1662,7 +1662,6 @@ static int public_state_init(struct public_state * state)
 				return AST_MODULE_LOAD_FAILURE;
 			}
 			ast_format_cap_append(channel_tech.capabilities, ast_format_slin, 0);
-			//chan_dongle_format_cap = channel_tech.capabilities;
 #elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
 			ast_format_set(&chan_dongle_format, AST_FORMAT_SLINEAR, 0);
 			if (!(channel_tech.capabilities = ast_format_cap_alloc())) {
diff --git a/chan_dongle.h b/chan_dongle.h
index b6e0436..362cffc 100644
--- a/chan_dongle.h
+++ b/chan_dongle.h
@@ -41,7 +41,6 @@ INLINE_DECL const char * dev_state2str_msg(dev_state_t state)
 #if ASTERISK_VERSION_NUM >= 100000 && ASTERISK_VERSION_NUM < 130000 /* 10-13 */
 /* Only linear is allowed */
 EXPORT_DECL struct ast_format chan_dongle_format;
-//EXPORT_DEF struct ast_format chan_dongle_format;
 EXPORT_DECL struct ast_format_cap * chan_dongle_format_cap;
 #endif /* ^10-13 */
 
diff --git a/channel.c b/channel.c
index 40dd629..e5dd43c 100644
--- a/channel.c
+++ b/channel.c
@@ -679,7 +679,7 @@ static struct ast_frame* channel_read (struct ast_channel* channel)
 
 		cpvt->a_read_frame.frametype = AST_FRAME_VOICE;
 #if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
-		cpvt->a_read_frame.subclass.format = ao2_bump(ast_format_slin);
+		cpvt->a_read_frame.subclass.format = ast_format_slin;
 #elif ASTERISK_VERSION_NUM >= 100000 /* 10-13 */
 		ast_format_copy(&cpvt->a_read_frame.subclass.format, &chan_dongle_format);
 #else /* 10- */
@@ -1265,21 +1265,29 @@ EXPORT_DEF struct ast_channel* new_channel(
 			ast_channel_tech_set(channel, &channel_tech);
 
 #if ASTERISK_VERSION_NUM >= 130000 /* 13+ */
-			ast_format_cap_append(ast_channel_nativeformats(channel), ast_format_slin, 0);
+			ast_channel_nativeformats_set(channel, channel_tech.capabilities);
+			ast_channel_set_rawreadformat(channel, ast_format_slin);
+			ast_channel_set_rawwriteformat(channel, ast_format_slin);
 			ast_channel_set_writeformat(channel, ast_format_slin);
 			ast_channel_set_readformat(channel, ast_format_slin);
 #elif ASTERISK_VERSION_NUM >= 110000 /* 11+ */
-			ast_format_set(ast_channel_readformat(channel), AST_FORMAT_SLINEAR, 0);
-			ast_format_set(ast_channel_writeformat(channel), AST_FORMAT_SLINEAR, 0);
-			ast_format_cap_set(ast_channel_nativeformats(channel), ast_channel_writeformat(channel));
+		        ast_format_cap_add(ast_channel_nativeformats(channel), &chan_dongle_format);
+		        ast_format_copy(ast_channel_rawreadformat(channel), &chan_dongle_format);
+		        ast_format_copy(ast_channel_rawwriteformat(channel), &chan_dongle_format);
+		        ast_format_copy(ast_channel_writeformat(channel), &chan_dongle_format);
+		        ast_format_copy(ast_channel_readformat(channel), &chan_dongle_format);
 #elif ASTERISK_VERSION_NUM >= 100000 /* 10+ */
-			ast_format_set(&channel->readformat, AST_FORMAT_SLINEAR, 0);
-			ast_format_set(&channel->writeformat, AST_FORMAT_SLINEAR, 0);
-			ast_format_cap_set(channel->nativeformats, &channel->writeformat);
+		        ast_format_cap_add(channel->nativeformats, &chan_dongle_format);
+		        ast_format_copy(&channel->rawreadformat, &chan_dongle_format);
+		        ast_format_copy(&channel->rawwriteformat, &chan_dongle_format);
+		        ast_format_copy(&channel->writeformat, &chan_dongle_format);
+		        ast_format_copy(&channel->readformat, &chan_dongle_format);
 #else /* 10- */
 			channel->nativeformats	= AST_FORMAT_SLINEAR;
-			channel->writeformat	= AST_FORMAT_SLINEAR;
+			channel->rawreadformat	= AST_FORMAT_SLINEAR;
+			channel->rawwriteformat	= AST_FORMAT_SLINEAR;
 			channel->readformat	= AST_FORMAT_SLINEAR;
+			channel->writeformat	= AST_FORMAT_SLINEAR;
 #endif /* ^10- */
 
 			if (ast_state == AST_STATE_RING)
