[asterisk-commits] wedhorn: branch wedhorn/skinny-subs r189201 - /team/wedhorn/skinny-subs/chann...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Apr 17 18:17:57 CDT 2009


Author: wedhorn
Date: Fri Apr 17 18:17:53 2009
New Revision: 189201

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=189201
Log:
Initial commit of changes to skinny subchannel handling and locking.

Modified:
    team/wedhorn/skinny-subs/channels/chan_skinny.c

Modified: team/wedhorn/skinny-subs/channels/chan_skinny.c
URL: http://svn.digium.com/svn-view/asterisk/team/wedhorn/skinny-subs/channels/chan_skinny.c?view=diff&rev=189201&r1=189200&r2=189201
==============================================================================
--- team/wedhorn/skinny-subs/channels/chan_skinny.c (original)
+++ team/wedhorn/skinny-subs/channels/chan_skinny.c Fri Apr 17 18:17:53 2009
@@ -71,13 +71,6 @@
 #include "asterisk/indications.h"
 #include "asterisk/linkedlists.h"
 
-#ifdef SKINNY_DEVMODE
-#define SKINNY_DEVONLY(code)	\
-	code
-#else
-#define SKINNY_DEVONLY(code)
-#endif
-
 /*************************************
  * Skinny/Asterisk Protocol Settings *
  *************************************/
@@ -96,6 +89,21 @@
 	SKINNY_CODEC_H261 = 100,
 	SKINNY_CODEC_H263 = 101
 };
+#define DEBUG_OFF 	0
+#define DEBUG_SIMPLE	(1 << 0)
+#define DEBUG_SUB	(1 << 1)
+#define DEBUG_RTP	(1 << 2)
+#define DEBUG_PACKET	(1 << 3)
+#define DEBUG_CORE	(1 << 4)
+#define DEBUG_DEVICE	(1 << 5)
+#define DEBUG_THREAD	(1 << 6)
+#define DEBUG_LOCK	(1 << 7)
+#define DEBUG_UNSET	(1 << 16)
+
+#define SKINNY_DEBUG(debug_type, code)		\
+	if (skinnydebug & (debug_type)) {	\
+		code;				\
+	}
 
 #define DEFAULT_SKINNY_PORT 2000
 #define DEFAULT_SKINNY_BACKLOG 2
@@ -167,16 +175,26 @@
 };
 static struct ast_jb_conf global_jbconf;
 
-#ifdef SKINNY_DEVMODE
-AST_THREADSTORAGE(message2str_threadbuf);
-#define MESSAGE2STR_BUFSIZE   35
-#endif
+//AST_THREADSTORAGE(message2str_threadbuf);
+//#define MESSAGE2STR_BUFSIZE   35
+
+AST_THREADSTORAGE(stimulus2str_threadbuf);
+#define STIMULUS2STR_BUFSIZE   35
+
+AST_THREADSTORAGE(softkey2str_threadbuf);
+#define SOFTKEY2STR_BUFSIZE   35
 
 AST_THREADSTORAGE(device2str_threadbuf);
 #define DEVICE2STR_BUFSIZE   15
 
 AST_THREADSTORAGE(control2str_threadbuf);
 #define CONTROL2STR_BUFSIZE   100
+
+AST_THREADSTORAGE(substate2str_threadbuf);
+#define SUBSTATE2STR_BUFSIZE   25
+
+AST_THREADSTORAGE(skinnystate2str_threadbuf);
+#define SKINNYSTATE2STR_BUFSIZE   25
 
 /*********************
  * Protocol Messages *
@@ -388,6 +406,11 @@
 	uint32_t space[3];
 };
 
+struct call_info_message2 {
+	char str1[40];
+	char str2[24];
+};
+
 #define FORWARD_STAT_MESSAGE 0x0090
 struct forward_stat_message {
 	uint32_t activeforward;
@@ -496,6 +519,11 @@
 #define DISPLAYTEXT_MESSAGE 0x0099
 struct displaytext_message {
 	char text[40];
+};
+
+struct displaytext_message_old {
+	char line1[20];
+	char line2[12];
 };
 
 #define CLEAR_NOTIFY_MESSAGE  0x0115
@@ -724,7 +752,7 @@
        \155: Default Router 3
        \156: Default Router 4
        \157: Default Router 5
-       \160: DNS Server 1
+       \160: DNS Server 1rec
        \161: DNS Server 2
        \162: DNS Server 3
        \163: DNS Server 4
@@ -916,6 +944,7 @@
 	struct version_res_message version;
 	struct button_template_res_message buttontemplate;
 	struct displaytext_message displaytext;
+	struct displaytext_message_old displaytextold;
 	struct display_prompt_status_message displaypromptstatus;
 	struct clear_prompt_message clearpromptstatus;
 	struct definetimedate_message definetimedate;
@@ -1043,12 +1072,47 @@
 #define SKINNY_CALLREMOTEMULTILINE 13
 #define SKINNY_INVALID 14
 
+/* The following sub states are unique to chan_skinny.
+   Do not send to core or skinny devices.
+   They relate to set_sub_state()   */
+#define SUBSTATE_NEW			101
+#define SUBSTATE_OFFHOOK		102
+#define SUBSTATE_DIAL			103
+#define SUBSTATE_PROGRESS		104
+#define SUBSTATE_RINGOUT		105
+#define SUBSTATE_BUSY			106
+#define SUBSTATE_CONGESTION		107
+#define SUBSTATE_RINGIN			108
+#define SUBSTATE_CALLWAIT		109
+#define SUBSTATE_CONNECTED		110
+#define SUBSTATE_HOLD			111
+#define SUBSTATE_TRANSFER		112
+#define SUBSTATE_AUTOANS		113
+#define SUBSTATE_HANGUP			114
+#define SUBSTATE_ONHOOK			115
+#define SUBSTATE_DIE			116
+#define SUBSTATE_CALLREMOTEMULTILINE	117
+#define SUBSTATE_CALLPARK		118
+#define SUBSTATE_INVALID		121
+#define SUBSTATE_DESTROY		122
+#define SUBSTATE_DIALING			123
+#define SUBSTATE_REORDER		131
+#define SUBSTATE_ANNOYTONE	132
+#define SUBSTATE_INBOUNDCALL	133
+#define SUBSTATE_DUMPSUB		134
+#define SUBSTATE_ENDCALL		135
+
 #define SKINNY_SILENCE 0x00
-#define SKINNY_DIALTONE 0x21
+#define SKINNY_INSIDEDIALTONE 0x21
+#define SKINNY_OUTSIDEDIALTONE 0x22
 #define SKINNY_BUSYTONE 0x23
-#define SKINNY_ALERT 0x24
-#define SKINNY_REORDER 0x25
+#define SKINNY_ALERTTONE 0x24
+#define SKINNY_REORDERTONE 0x25
 #define SKINNY_CALLWAITTONE 0x2D
+#define SKINNY_ZIPZIP 0x31
+#define SKINNY_ZIP 0x32
+#define SKINNY_BEEPBONK 0x33
+#define SKINNY_HOLDTONE 0x35
 #define SKINNY_NOTONE 0x7F
 
 #define SKINNY_LAMP_OFF 1
@@ -1061,6 +1125,8 @@
 #define SKINNY_RING_INSIDE 2
 #define SKINNY_RING_OUTSIDE 3
 #define SKINNY_RING_FEATURE 4
+#define SKINNY_RING_FLASHONLY 5
+#define SKINNY_RING_PRECEDENCE 6
 
 #define SKINNY_CFWD_ALL       (1 << 0)
 #define SKINNY_CFWD_BUSY      (1 << 1)
@@ -1109,7 +1175,6 @@
 static int matchdigittimeout = 3000;
 
 struct skinny_subchannel {
-	ast_mutex_t lock;
 	struct ast_channel *owner;
 	struct ast_rtp_instance *rtp;
 	struct ast_rtp_instance *vrtp;
@@ -1125,9 +1190,35 @@
 	int alreadygone;
 	int blindxfer;
 	int xferor;
-
-
-	AST_LIST_ENTRY(skinny_subchannel) list;
+	int substate;
+	int devstate;
+	pthread_t thread;
+	int thread_die;
+	char reference;
+	int killdialingthread;
+	int killendcallthread;
+	int ringermode;
+	int autoans;
+	int autoans_time;
+	int autoans_tone;
+	int autohangup;
+	int dialing;
+	int hangingup;
+	int endcalltonetime;
+	char label[42];
+	pthread_t dialingthread;
+	char exten[AST_MAX_EXTENSION];
+	int calltype;
+	int locks;
+	char callingname[AST_MAX_EXTENSION];
+	char callingnum[AST_MAX_EXTENSION];
+	char calledname[AST_MAX_EXTENSION];
+	char callednum[AST_MAX_EXTENSION];
+	char oldcallingname[20];
+	char oldcallingnum[12];
+	
+	AST_LIST_ENTRY(skinny_subchannel) llist;
+	AST_LIST_ENTRY(skinny_subchannel) dlist;
 	struct skinny_subchannel *related;
 	struct skinny_line *parent;
 };
@@ -1180,17 +1271,16 @@
 	int onhooktime;					\
 	int msgstate;					\
 	int immediate;					\
-	int hookstate;					\
 	int nat;					\
 	int canreinvite;				\
 	int prune;
 
 struct skinny_line {
 	SKINNY_LINE_OPTIONS
-	ast_mutex_t lock;
 	struct ast_event_sub *mwi_event_sub; /* Event based MWI */
 	struct skinny_subchannel *activesub;
-	AST_LIST_HEAD(, skinny_subchannel) sub;
+	struct skinny_subchannel *startfortraverse;
+	AST_LIST_HEAD(, skinny_subchannel) subs;
 	AST_LIST_ENTRY(skinny_line) list;
 	AST_LIST_ENTRY(skinny_line) all;
 	struct skinny_device *device;
@@ -1215,14 +1305,12 @@
 	.getforward = 0,
  	.needdestroy = 0,
 	.prune = 0,
-	.hookstate = SKINNY_ONHOOK,
 };
 struct skinny_line_options *default_line = &default_line_struct;
 
 static AST_LIST_HEAD_STATIC(lines, skinny_line);
 
 struct skinny_speeddial {
-	ast_mutex_t lock;
 	char label[42];
 	char context[AST_MAX_CONTEXT];
 	char exten[AST_MAX_EXTENSION];
@@ -1236,7 +1324,6 @@
 };
 
 struct skinny_addon {
-	ast_mutex_t lock;
 	char type[10];
 	AST_LIST_ENTRY(skinny_addon) list;
 	struct skinny_device *parent;
@@ -1259,8 +1346,15 @@
 	int transfer;						\
 	int callwaiting;					\
 	int mwiblink;						\
+	int hookstate;						\
 	int dnd;						\
-	int prune;
+	int prune;						\
+	int autohangup;						\
+	int ringermode;						\
+	int ringermodetone;					\
+	int devicetone;						\
+	int locks;						\
+	int rtptone;
 
 struct skinny_device {
 	SKINNY_DEVICE_OPTIONS
@@ -1272,6 +1366,9 @@
 	struct ast_ha *ha;
 	struct skinnysession *session;
 	struct skinny_line *activeline;
+	struct skinny_subchannel *activesub;
+//	struct skinny_subchannel *workingsub;
+	AST_LIST_HEAD(, skinny_subchannel) subs;
 	AST_LIST_HEAD(, skinny_line) lines;
 	AST_LIST_HEAD(, skinny_speeddial) speeddials;
 	AST_LIST_HEAD(, skinny_addon) addons;
@@ -1287,9 +1384,16 @@
  	.mwiblink = 0,
  	.dnd = 0,
  	.confcapability = AST_FORMAT_ULAW | AST_FORMAT_ALAW,
- 	.capability = 0,
+	.capability = 0,
 	.prune = 0,
-};
+	.hookstate = SKINNY_ONHOOK,
+	.autohangup = 0,
+	.ringermode = SKINNY_RING_OFF,
+	.devicetone = SKINNY_SILENCE,
+	.rtptone = SKINNY_SILENCE,
+	.locks = 0,
+};
+
 struct skinny_device_options *default_device = &default_device_struct;
 	
 static AST_LIST_HEAD_STATIC(devices, skinny_device);
@@ -1305,7 +1409,7 @@
 
 struct skinnysession {
 	pthread_t t;
-	ast_mutex_t lock;
+//	ast_mutex_t lock;
 	struct sockaddr_in sin;
 	int fd;
 	char inbuf[SKINNY_MAX_PACKET];
@@ -1327,9 +1431,12 @@
 static int skinny_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
 static int skinny_senddigit_begin(struct ast_channel *ast, char digit);
 static int skinny_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration);
-static int handle_time_date_req_message(struct skinny_req *req, struct skinnysession *s);
+//static int handle_time_date_req_message(struct skinny_req *req, struct skinnysession *s);
 static void mwi_event_cb(const struct ast_event *event, void *userdata);
 static int skinny_reload(void);
+static struct skinny_subchannel *set_sub_state(struct skinny_subchannel *sub, int state);
+//static struct skinny_subchannel *set_workingsub_state(struct skinny_device *d, int state);
+static void destroy_sub(struct skinny_subchannel *sub);
 
 static const struct ast_channel_tech skinny_tech = {
 	.type = "Skinny",
@@ -1353,563 +1460,11 @@
 static int skinny_extensionstate_cb(char *context, char* exten, int state, void *data);
 static int skinny_transfer(struct skinny_subchannel *sub);
 
-static void *get_button_template(struct skinnysession *s, struct button_definition_template *btn)
-{
-	struct skinny_device *d = s->device;
-	struct skinny_addon *a;
-	int i;
-
-	switch (d->type) {
-		case SKINNY_DEVICE_30SPPLUS:
-		case SKINNY_DEVICE_30VIP:
-			/* 13 rows, 2 columns */
-			for (i = 0; i < 4; i++)
-				(btn++)->buttonDefinition = BT_CUST_LINE;
-			(btn++)->buttonDefinition = BT_REDIAL;
-			(btn++)->buttonDefinition = BT_VOICEMAIL;
-			(btn++)->buttonDefinition = BT_CALLPARK;
-			(btn++)->buttonDefinition = BT_FORWARDALL;
-			(btn++)->buttonDefinition = BT_CONFERENCE;
-			for (i = 0; i < 4; i++)
-				(btn++)->buttonDefinition = BT_NONE;
-			for (i = 0; i < 13; i++)
-				(btn++)->buttonDefinition = BT_SPEEDDIAL;
-			
-			break;
-		case SKINNY_DEVICE_12SPPLUS:
-		case SKINNY_DEVICE_12SP:
-		case SKINNY_DEVICE_12:
-			/* 6 rows, 2 columns */
-			for (i = 0; i < 2; i++)
-				(btn++)->buttonDefinition = BT_CUST_LINE;
-			for (i = 0; i < 4; i++)
-				(btn++)->buttonDefinition = BT_SPEEDDIAL;
-			(btn++)->buttonDefinition = BT_HOLD;
-			(btn++)->buttonDefinition = BT_REDIAL;
-			(btn++)->buttonDefinition = BT_TRANSFER;
-			(btn++)->buttonDefinition = BT_FORWARDALL;
-			(btn++)->buttonDefinition = BT_CALLPARK;
-			(btn++)->buttonDefinition = BT_VOICEMAIL;
-			break;
-		case SKINNY_DEVICE_7910:
-			(btn++)->buttonDefinition = BT_LINE;
-			(btn++)->buttonDefinition = BT_HOLD;
-			(btn++)->buttonDefinition = BT_TRANSFER;
-			(btn++)->buttonDefinition = BT_DISPLAY;
-			(btn++)->buttonDefinition = BT_VOICEMAIL;
-			(btn++)->buttonDefinition = BT_CONFERENCE;
-			(btn++)->buttonDefinition = BT_FORWARDALL;
-			for (i = 0; i < 2; i++)
-				(btn++)->buttonDefinition = BT_SPEEDDIAL;
-			(btn++)->buttonDefinition = BT_REDIAL;
-			break;
-		case SKINNY_DEVICE_7960:
-		case SKINNY_DEVICE_7961:
-		case SKINNY_DEVICE_7961GE:
-		case SKINNY_DEVICE_7962:
-		case SKINNY_DEVICE_7965:
-			for (i = 0; i < 6; i++)
-				(btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
-			break;
-		case SKINNY_DEVICE_7940:
-		case SKINNY_DEVICE_7941:
-		case SKINNY_DEVICE_7941GE:
-		case SKINNY_DEVICE_7942:
-		case SKINNY_DEVICE_7945:
-			for (i = 0; i < 2; i++)
-				(btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
-			break;
-		case SKINNY_DEVICE_7935:
-		case SKINNY_DEVICE_7936:
-			for (i = 0; i < 2; i++)
-				(btn++)->buttonDefinition = BT_LINE;
-			break;
-		case SKINNY_DEVICE_ATA186:
-			(btn++)->buttonDefinition = BT_LINE;
-			break;
-		case SKINNY_DEVICE_7970:
-		case SKINNY_DEVICE_7971:
-		case SKINNY_DEVICE_7975:
-		case SKINNY_DEVICE_CIPC:
-			for (i = 0; i < 8; i++)
-				(btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
-			break;
-		case SKINNY_DEVICE_7985:
-			/* XXX I have no idea what the buttons look like on these. */
-			ast_log(LOG_WARNING, "Unsupported device type '%d (7985)' found.\n", d->type);
-			break;
-		case SKINNY_DEVICE_7912:
-		case SKINNY_DEVICE_7911:
-		case SKINNY_DEVICE_7905:
-			(btn++)->buttonDefinition = BT_LINE;
-			(btn++)->buttonDefinition = BT_HOLD;
-			break;
-		case SKINNY_DEVICE_7920:
-			/* XXX I don't know if this is right. */
-			for (i = 0; i < 4; i++)
-				(btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
-			break;
-		case SKINNY_DEVICE_7921:
-			for (i = 0; i < 6; i++)
-				(btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
-			break;
-		case SKINNY_DEVICE_7902:
-			ast_log(LOG_WARNING, "Unsupported device type '%d (7902)' found.\n", d->type);
-			break;
-		case SKINNY_DEVICE_7906:
-			ast_log(LOG_WARNING, "Unsupported device type '%d (7906)' found.\n", d->type);
-			break;
-		case SKINNY_DEVICE_7931:
-			ast_log(LOG_WARNING, "Unsupported device type '%d (7931)' found.\n", d->type);
-			break;
-		case SKINNY_DEVICE_7937:
-			ast_log(LOG_WARNING, "Unsupported device type '%d (7937)' found.\n", d->type);
-			break;
-		case SKINNY_DEVICE_7914:
-			ast_log(LOG_WARNING, "Unsupported device type '%d (7914)' found.  Expansion module registered by itself?\n", d->type);
-			break;
-		case SKINNY_DEVICE_SCCPGATEWAY_AN:
-		case SKINNY_DEVICE_SCCPGATEWAY_BRI:
-			ast_log(LOG_WARNING, "Unsupported device type '%d (SCCP gateway)' found.\n", d->type);
-			break;
-		default:
-			ast_log(LOG_WARNING, "Unknown device type '%d' found.\n", d->type);
-			break;
-	}
-
-	AST_LIST_LOCK(&d->addons);
-	AST_LIST_TRAVERSE(&d->addons, a, list) {
-		if (!strcasecmp(a->type, "7914")) {
-			for (i = 0; i < 14; i++)
-				(btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
-		} else {
-			ast_log(LOG_WARNING, "Unknown addon type '%s' found.  Skipping.\n", a->type);
-		}
-	}
-	AST_LIST_UNLOCK(&d->addons);
-
-	return btn;
-}
-
-static struct skinny_req *req_alloc(size_t size, int response_message)
-{
-	struct skinny_req *req;
-
-	if (!(req = ast_calloc(1, skinny_header_size + size + 4)))
-		return NULL;
-
-	req->len = htolel(size+4);
-	req->e = htolel(response_message);
-
-	return req;
-}
-
-static struct skinny_line *find_line_by_instance(struct skinny_device *d, int instance)
-{
-	struct skinny_line *l;
-
-	/*Dialing from on hook or on a 7920 uses instance 0 in requests
-	  but we need to start looking at instance 1 */
-
-	if (!instance)
-		instance = 1;
-
-	AST_LIST_TRAVERSE(&d->lines, l, list){
-		if (l->instance == instance)
-			break;
-	}
-
-	if (!l) {
-		ast_log(LOG_WARNING, "Could not find line with instance '%d' on device '%s'\n", instance, d->name);
-	}
-	return l;
-}
-
-static struct skinny_line *find_line_by_name(const char *dest)
-{
-	struct skinny_line *l;
-	struct skinny_line *tmpl = NULL;
-	struct skinny_device *d;
-	char line[256];
-	char *at;
-	char *device;
-	int checkdevice = 0;
-
-	ast_copy_string(line, dest, sizeof(line));
-	at = strchr(line, '@');
-	if (at)
-		*at++ = '\0';
-	device = at;
-
-	if (!ast_strlen_zero(device))
-		checkdevice = 1;
-
-	AST_LIST_LOCK(&devices);
-	AST_LIST_TRAVERSE(&devices, d, list){
-		if (checkdevice && tmpl)
-			break;
-		else if (!checkdevice) {
-			/* This is a match, since we're checking for line on every device. */
-		} else if (!strcasecmp(d->name, device)) {
-			if (skinnydebug)
-				ast_verb(2, "Found device: %s\n", d->name);
-		} else
-			continue;
-
-		/* Found the device (or we don't care which device) */
-		AST_LIST_TRAVERSE(&d->lines, l, list){
-			/* Search for the right line */
-			if (!strcasecmp(l->name, line)) {
-				if (tmpl) {
-					ast_verb(2, "Ambiguous line name: %s\n", line);
-					AST_LIST_UNLOCK(&devices);
-					return NULL;
-				} else
-					tmpl = l;
-			}
-		}
-	}
-	AST_LIST_UNLOCK(&devices);
-	return tmpl;
-}
-
-/*!
- * implement the setvar config line
- */
-static struct ast_variable *add_var(const char *buf, struct ast_variable *list)
-{
-	struct ast_variable *tmpvar = NULL;
-	char *varname = ast_strdupa(buf), *varval = NULL;
-
-	if ((varval = strchr(varname,'='))) {
-		*varval++ = '\0';
-		if ((tmpvar = ast_variable_new(varname, varval, ""))) {
-			tmpvar->next = list;
-			list = tmpvar;
-		}
-	}
-	return list;
-}
-
-/* It's quicker/easier to find the subchannel when we know the instance number too */
-static struct skinny_subchannel *find_subchannel_by_instance_reference(struct skinny_device *d, int instance, int reference)
-{
-	struct skinny_line *l = find_line_by_instance(d, instance);
-	struct skinny_subchannel *sub;
-
-	if (!l) {
-		return NULL;
-	}
-
-	/* 7920 phones set call reference to 0, so use the first
-	   sub-channel on the list.
-           This MIGHT need more love to be right */
-	if (!reference)
-		sub = AST_LIST_FIRST(&l->sub);
-	else {
-		AST_LIST_TRAVERSE(&l->sub, sub, list) {
-			if (sub->callid == reference)
-				break;
-		}
-	}
-	if (!sub) {
-		ast_log(LOG_WARNING, "Could not find subchannel with reference '%d' on '%s'\n", reference, d->name);
-	}
-	return sub;
-}
-
-/* Find the subchannel when we only have the callid - this shouldn't happen often */
-static struct skinny_subchannel *find_subchannel_by_reference(struct skinny_device *d, int reference)
-{
-	struct skinny_line *l;
-	struct skinny_subchannel *sub = NULL;
-
-	AST_LIST_TRAVERSE(&d->lines, l, list){
-		AST_LIST_TRAVERSE(&l->sub, sub, list){
-			if (sub->callid == reference)
-				break;
-		}
-		if (sub)
-			break;
-	}
-
-	if (!l) {
-		ast_log(LOG_WARNING, "Could not find any lines that contained a subchannel with reference '%d' on device '%s'\n", reference, d->name);
-	} else {
-		if (!sub) {
-			ast_log(LOG_WARNING, "Could not find subchannel with reference '%d' on '%s@%s'\n", reference, l->name, d->name);
-		}
-	}
-	return sub;
-}
-
-static struct skinny_speeddial *find_speeddial_by_instance(struct skinny_device *d, int instance, int isHint)
-{
-	struct skinny_speeddial *sd;
-
-	AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
-		if (sd->isHint == isHint && sd->instance == instance)
-			break;
-	}
-
-	if (!sd) {
-		ast_log(LOG_WARNING, "Could not find speeddial with instance '%d' on device '%s'\n", instance, d->name);
-	}
-	return sd;
-}
-
-static int codec_skinny2ast(enum skinny_codecs skinnycodec)
-{
-	switch (skinnycodec) {
-	case SKINNY_CODEC_ALAW:
-		return AST_FORMAT_ALAW;
-	case SKINNY_CODEC_ULAW:
-		return AST_FORMAT_ULAW;
-	case SKINNY_CODEC_G723_1:
-		return AST_FORMAT_G723_1;
-	case SKINNY_CODEC_G729A:
-		return AST_FORMAT_G729A;
-	case SKINNY_CODEC_G726_32:
-		return AST_FORMAT_G726_AAL2; /* XXX Is this right? */
-	case SKINNY_CODEC_H261:
-		return AST_FORMAT_H261;
-	case SKINNY_CODEC_H263:
-		return AST_FORMAT_H263;
-	default:
-		return 0;
-	}
-}
-
-static int codec_ast2skinny(int astcodec)
-{
-	switch (astcodec) {
-	case AST_FORMAT_ALAW:
-		return SKINNY_CODEC_ALAW;
-	case AST_FORMAT_ULAW:
-		return SKINNY_CODEC_ULAW;
-	case AST_FORMAT_G723_1:
-		return SKINNY_CODEC_G723_1;
-	case AST_FORMAT_G729A:
-		return SKINNY_CODEC_G729A;
-	case AST_FORMAT_G726_AAL2: /* XXX Is this right? */
-		return SKINNY_CODEC_G726_32;
-	case AST_FORMAT_H261:
-		return SKINNY_CODEC_H261;
-	case AST_FORMAT_H263:
-		return SKINNY_CODEC_H263;
-	default:
-		return 0;
-	}
-}
-
-static int set_callforwards(struct skinny_line *l, const char *cfwd, int cfwdtype)
-{
-	if (!l)
-		return 0;
-
-	if (!ast_strlen_zero(cfwd)) {
-		if (cfwdtype & SKINNY_CFWD_ALL) {
-			l->cfwdtype |= SKINNY_CFWD_ALL;
-			ast_copy_string(l->call_forward_all, cfwd, sizeof(l->call_forward_all));
-		}
-		if (cfwdtype & SKINNY_CFWD_BUSY) {
-			l->cfwdtype |= SKINNY_CFWD_BUSY;
-			ast_copy_string(l->call_forward_busy, cfwd, sizeof(l->call_forward_busy));
-		}
-		if (cfwdtype & SKINNY_CFWD_NOANSWER) {
-			l->cfwdtype |= SKINNY_CFWD_NOANSWER;
-			ast_copy_string(l->call_forward_noanswer, cfwd, sizeof(l->call_forward_noanswer));
-		}
-	} else {
-		if (cfwdtype & SKINNY_CFWD_ALL) {
-			l->cfwdtype &= ~SKINNY_CFWD_ALL;
-			memset(l->call_forward_all, 0, sizeof(l->call_forward_all));
-		}
-		if (cfwdtype & SKINNY_CFWD_BUSY) {
-			l->cfwdtype &= ~SKINNY_CFWD_BUSY;
-			memset(l->call_forward_busy, 0, sizeof(l->call_forward_busy));
-		}
-		if (cfwdtype & SKINNY_CFWD_NOANSWER) {
-			l->cfwdtype &= ~SKINNY_CFWD_NOANSWER;
-			memset(l->call_forward_noanswer, 0, sizeof(l->call_forward_noanswer));
-		}
-	}
-	return l->cfwdtype;
-}
-
-static void cleanup_stale_contexts(char *new, char *old)
-{
-	char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
-
-	while ((oldcontext = strsep(&old, "&"))) {
-		stalecontext = '\0';
-		ast_copy_string(newlist, new, sizeof(newlist));
-		stringp = newlist;
-		while ((newcontext = strsep(&stringp, "&"))) {
-			if (strcmp(newcontext, oldcontext) == 0) {
-				/* This is not the context you're looking for */
-				stalecontext = '\0';
-				break;
-			} else if (strcmp(newcontext, oldcontext)) {
-				stalecontext = oldcontext;
-			}
-			
-		}
-		if (stalecontext)
-			ast_context_destroy(ast_context_find(stalecontext), "Skinny");
-	}
-}
-
-static void register_exten(struct skinny_line *l)
-{
-	char multi[256];
-	char *stringp, *ext, *context;
-
-	if (ast_strlen_zero(regcontext))
-		return;
-
-	ast_copy_string(multi, S_OR(l->regexten, l->name), sizeof(multi));
-	stringp = multi;
-	while ((ext = strsep(&stringp, "&"))) {
-		if ((context = strchr(ext, '@'))) {
-			*context++ = '\0'; /* split ext at context */
-			if (!ast_context_find(context)) {
-				ast_log(LOG_WARNING, "Context %s must exist in regcontext= in skinny.conf!\n", context);
-				continue;
-			}
-		} else {
-			context = regcontext;
-		}
-		ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
-			 ast_strdup(l->name), ast_free_ptr, "Skinny");
-	}
-}
-
-static void unregister_exten(struct skinny_line *l)
-{
-	char multi[256];
-	char *stringp, *ext, *context;
-
-	if (ast_strlen_zero(regcontext))
-		return;
-
-	ast_copy_string(multi, S_OR(l->regexten, l->name), sizeof(multi));
-	stringp = multi;
-	while ((ext = strsep(&stringp, "&"))) {
-		if ((context = strchr(ext, '@'))) {
-			*context++ = '\0'; /* split ext at context */
-			if (!ast_context_find(context)) {
-				ast_log(LOG_WARNING, "Context %s must exist in regcontext= in skinny.conf!\n", context);
-				continue;
-			}
-		} else {
-			context = regcontext;
-		}
-		ast_context_remove_extension(context, ext, 1, NULL);
-	}
-}
-
-static int skinny_register(struct skinny_req *req, struct skinnysession *s)
-{
-	struct skinny_device *d;
-	struct skinny_line *l;
-	struct skinny_speeddial *sd;
-	struct sockaddr_in sin;
-	socklen_t slen;
-	int instance;
-
-	AST_LIST_LOCK(&devices);
-	AST_LIST_TRAVERSE(&devices, d, list){
-		if (!strcasecmp(req->data.reg.name, d->id)
-				&& ast_apply_ha(d->ha, &(s->sin))) {
-			s->device = d;
-			d->type = letohl(req->data.reg.type);
-			if (ast_strlen_zero(d->version_id)) {
-				ast_copy_string(d->version_id, version_id, sizeof(d->version_id));
-			}
-			d->registered = 1;
-			d->session = s;
-
-			slen = sizeof(sin);
-			if (getsockname(s->fd, (struct sockaddr *)&sin, &slen)) {
-				ast_log(LOG_WARNING, "Cannot get socket name\n");
-				sin.sin_addr = __ourip;
-			}
-			d->ourip = sin.sin_addr;
-
-			AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
-				sd->stateid = ast_extension_state_add(sd->context, sd->exten, skinny_extensionstate_cb, sd);
-			}
-			instance = 0;
-			AST_LIST_TRAVERSE(&d->lines, l, list) {
-				instance++;
-			}
-			AST_LIST_TRAVERSE(&d->lines, l, list) {
-				/* FIXME: All sorts of issues will occur if this line is already connected to a device */
-				if (l->device) {
-					ast_verb(1, "Line %s already connected to %s. Not connecting to %s.\n", l->name, l->device->name, d->name);
-				} else {
-					l->device = d;
-					l->capability = l->confcapability & d->capability;
-					l->prefs = l->confprefs;
-					if (!l->prefs.order[0]) {
-						l->prefs = d->confprefs;
-					}
-					/* l->capability = d->capability;
-					l->prefs = d->prefs; */
-					l->instance = instance;
-					l->newmsgs = ast_app_has_voicemail(l->mailbox, NULL);
-					set_callforwards(l, NULL, 0);
-					register_exten(l);
-					/* initialize MWI on line and device */
-					mwi_event_cb(0, l);
-					ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name);
-				}
-				--instance;
-			}
-			break;
-		}
-	}
-	AST_LIST_UNLOCK(&devices);
-	if (!d) {
-		return 0;
-	}
-	return 1;
-}
-
-static int skinny_unregister(struct skinny_req *req, struct skinnysession *s)
-{
-	struct skinny_device *d;
-	struct skinny_line *l;
-	struct skinny_speeddial *sd;
-
-	d = s->device;
-
-	if (d) {
-		d->session = NULL;
-		d->registered = 0;
-
-		AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
-			if (sd->stateid > -1)
-				ast_extension_state_del(sd->stateid, NULL);
-		}
-		AST_LIST_TRAVERSE(&d->lines, l, list) {
-			if (l->device == d) {
-				l->device = NULL;
-				l->capability = 0;
-				ast_parse_allow_disallow(&l->prefs, &l->capability, "all", 0);			
-				l->instance = 0;
-				unregister_exten(l);
-				ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Skinny/%s@%s", l->name, d->name);
-			}
-		}
-	}
-
-	return -1; /* main loop will destroy the session */
-}
-
-#ifdef SKINNY_DEVMODE
-static char *message2str(int type)
+/* -------------------------------------------------------------------------------------------------------------------------------------------------------------- 
+ *	STRING HANDLING FUNCTIONS
+ * --------------------------------------------------------------------------------------------------------------------------------------------------------------  */
+
+/*static char *message2str(int type)
 {
 	char *tmp;
 
@@ -2036,841 +1591,104 @@
 		snprintf(tmp, MESSAGE2STR_BUFSIZE, "UNKNOWN_MESSAGE-%d", type);
 		return tmp;
 	}
-}
-#endif
-
-static int transmit_response(struct skinny_device *d, struct skinny_req *req)
-{
-	struct skinnysession *s = d->session;
-	int res = 0;
-
-	if (!s) {
-		ast_log(LOG_WARNING, "Asked to transmit to a non-existent session!\n");
-		return -1;
-	}
-
-	ast_mutex_lock(&s->lock);
-
-	SKINNY_DEVONLY(if (skinnydebug>1) ast_verb(4, "Transmitting %s to %s\n", message2str(req->e), d->name);)
-
-	if (letohl(req->len > SKINNY_MAX_PACKET) || letohl(req->len < 0)) {
-		ast_log(LOG_WARNING, "transmit_response: the length of the request is out of bounds\n");
-		ast_mutex_unlock(&s->lock);
-		return -1;
-	}
-
-	memset(s->outbuf, 0, sizeof(s->outbuf));
-	memcpy(s->outbuf, req, skinny_header_size);
-	memcpy(s->outbuf+skinny_header_size, &req->data, letohl(req->len));
-
-	res = write(s->fd, s->outbuf, letohl(req->len)+8);
-	
-	if (res != letohl(req->len)+8) {
-		ast_log(LOG_WARNING, "Transmit: write only sent %d out of %d bytes: %s\n", res, letohl(req->len)+8, strerror(errno));
-		if (res == -1) {
-			if (skinnydebug)
-				ast_log(LOG_WARNING, "Transmit: Skinny Client was lost, unregistering\n");
-			skinny_unregister(NULL, s);
-		}
-		
-	}
-	
-	ast_free(req);
-	ast_mutex_unlock(&s->lock);
-	return 1;
-}
-
-static void transmit_speaker_mode(struct skinny_device *d, int mode)
-{
-	struct skinny_req *req;
-
-	if (!(req = req_alloc(sizeof(struct set_speaker_message), SET_SPEAKER_MESSAGE)))
-		return;
-
-	req->data.setspeaker.mode = htolel(mode);
-	transmit_response(d, req);
-}
-/*
-static void transmit_microphone_mode(struct skinny_device *d, int mode)
-{
-	struct skinny_req *req;
-
-	if (!(req = req_alloc(sizeof(struct set_microphone_message), SET_MICROPHONE_MESSAGE)))
-		return;
-
-	req->data.setmicrophone.mode = htolel(mode);
-	transmit_response(d, req);
-}
-*/
-
-static void transmit_callinfo(struct skinny_device *d, const char *fromname, const char *fromnum, const char *toname, const char *tonum, int instance, int callid, int calltype)
-{
-	struct skinny_req *req;
-
-	/* We should not be able to get here without a device */
-	if (!d)
-		return;
-
-	if (!(req = req_alloc(sizeof(struct call_info_message), CALL_INFO_MESSAGE)))
-		return;
-
-	if (skinnydebug)
-			ast_verb(1, "Setting Callinfo to %s(%s) from %s(%s) on %s(%d)\n", fromname, fromnum, toname, tonum, d->name, instance);
-
-	if (fromname) {
-		ast_copy_string(req->data.callinfo.callingPartyName, fromname, sizeof(req->data.callinfo.callingPartyName));
-	}
-	if (fromnum) {
-		ast_copy_string(req->data.callinfo.callingParty, fromnum, sizeof(req->data.callinfo.callingParty));
-	}
-	if (toname) {
-		ast_copy_string(req->data.callinfo.calledPartyName, toname, sizeof(req->data.callinfo.calledPartyName));
-	}
-	if (tonum) {
-		ast_copy_string(req->data.callinfo.calledParty, tonum, sizeof(req->data.callinfo.calledParty));
-	}
-	req->data.callinfo.instance = htolel(instance);
-	req->data.callinfo.reference = htolel(callid);
-	req->data.callinfo.type = htolel(calltype);
-	transmit_response(d, req);
-}
-
-static void transmit_connect(struct skinny_device *d, struct skinny_subchannel *sub)
-{
-	struct skinny_req *req;
-	struct skinny_line *l = sub->parent;
-	struct ast_format_list fmt;
-
-	if (!(req = req_alloc(sizeof(struct open_receive_channel_message), OPEN_RECEIVE_CHANNEL_MESSAGE)))
-		return;
-
-	fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability));
-
-	req->data.openreceivechannel.conferenceId = htolel(sub->callid);
-	req->data.openreceivechannel.partyId = htolel(sub->callid);
-	req->data.openreceivechannel.packets = htolel(fmt.cur_ms);
-	req->data.openreceivechannel.capability = htolel(codec_ast2skinny(fmt.bits));
-	req->data.openreceivechannel.echo = htolel(0);
-	req->data.openreceivechannel.bitrate = htolel(0);
-	transmit_response(d, req);
-}
-
-static void transmit_tone(struct skinny_device *d, int tone, int instance, int reference)
-{
-	struct skinny_req *req;
-
-	if (tone == SKINNY_NOTONE) {
-		/* This is bad, mmm'kay? */
-		return;
-	}
-
-	if (tone > 0) {
-		if (!(req = req_alloc(sizeof(struct start_tone_message), START_TONE_MESSAGE)))
-			return;
-		req->data.starttone.tone = htolel(tone);
-		req->data.starttone.instance = htolel(instance);
-		req->data.starttone.reference = htolel(reference);
-	} else {
-		if (!(req = req_alloc(sizeof(struct stop_tone_message), STOP_TONE_MESSAGE)))
-			return;
-		req->data.stoptone.instance = htolel(instance);
-		req->data.stoptone.reference = htolel(reference);
-	}
-
-	//Bad, tone is already set so this is redundant and a change to the if above
-	//may lead to issues where we try to set a tone to a stop_tone_message
-	//if (tone > 0) {
-	//	req->data.starttone.tone = htolel(tone);
-	//}
-	transmit_response(d, req);
-}
-
-static void transmit_selectsoftkeys(struct skinny_device *d, int instance, int callid, int softkey)
-{
-	struct skinny_req *req;
-
-	if (!(req = req_alloc(sizeof(struct select_soft_keys_message), SELECT_SOFT_KEYS_MESSAGE)))
-		return;
-
-	req->data.selectsoftkey.instance = htolel(instance);
-	req->data.selectsoftkey.reference = htolel(callid);
-	req->data.selectsoftkey.softKeySetIndex = htolel(softkey);
-	req->data.selectsoftkey.validKeyMask = htolel(0xFFFFFFFF);
-	transmit_response(d, req);
-}
-
-static void transmit_lamp_indication(struct skinny_device *d, int stimulus, int instance, int indication)
-{
-	struct skinny_req *req;
-
-	if (!(req = req_alloc(sizeof(struct set_lamp_message), SET_LAMP_MESSAGE)))
-		return;
-
-	req->data.setlamp.stimulus = htolel(stimulus);
-	req->data.setlamp.stimulusInstance = htolel(instance);
-	req->data.setlamp.deviceStimulus = htolel(indication);
-	transmit_response(d, req);
-}
-
-static void transmit_ringer_mode(struct skinny_device *d, int mode)
-{
-	struct skinny_req *req;
-
-	if (skinnydebug)
-		ast_verb(1, "Setting ringer mode to '%d'.\n", mode);
-
-	if (!(req = req_alloc(sizeof(struct set_ringer_message), SET_RINGER_MESSAGE)))
-		return;
-
-	req->data.setringer.ringerMode = htolel(mode);
-	/* XXX okay, I don't quite know what this is, but here's what happens (on a 7960).
-	   Note: The phone will always show as ringing on the display.
-
-	   1: phone will audibly ring over and over
-	   2: phone will audibly ring only once
-	   any other value, will NOT cause the phone to audibly ring
-	*/
-	req->data.setringer.unknown1 = htolel(1);
-	/* XXX the value here doesn't seem to change anything.  Must be higher than 0.
-	   Perhaps a packet capture can shed some light on this. */
-	req->data.setringer.unknown2 = htolel(1);
-	transmit_response(d, req);
-}
-
-static void transmit_displaymessage(struct skinny_device *d, const char *text, int instance, int reference)
-{
-	struct skinny_req *req;
-
-	if (text == 0) {
-		if (!(req = req_alloc(0, CLEAR_DISPLAY_MESSAGE)))
-			return;
-
-		//what do we want hear CLEAR_DISPLAY_MESSAGE or CLEAR_PROMPT_STATUS???
-		//if we are clearing the display, it appears there is no instance and refernece info (size 0)
-		//req->data.clearpromptstatus.lineInstance = instance;
-		//req->data.clearpromptstatus.callReference = reference;
-
-		/* send datetime message. We have to do it here because it will clear the display on the phone if we do it elsewhere */
-		handle_time_date_req_message(NULL, d->session);
-
-		if (skinnydebug)
-			ast_verb(1, "Clearing Display\n");
-	} else {
-		if (!(req = req_alloc(sizeof(struct displaytext_message), DISPLAYTEXT_MESSAGE)))
-			return;
-
-		ast_copy_string(req->data.displaytext.text, text, sizeof(req->data.displaytext.text));
-		if (skinnydebug)
-			ast_verb(1, "Displaying message '%s'\n", req->data.displaytext.text);
-	}
-
-	transmit_response(d, req);
-}
-
-static void transmit_displaynotify(struct skinny_device *d, const char *text, int t)
-{
-	struct skinny_req *req;
-
-	if (!(req = req_alloc(sizeof(struct display_notify_message), DISPLAY_NOTIFY_MESSAGE)))
-		return;
-
-	ast_copy_string(req->data.displaynotify.displayMessage, text, sizeof(req->data.displaynotify.displayMessage));
-	req->data.displaynotify.displayTimeout = htolel(t);
-
-	if (skinnydebug)
-		ast_verb(1, "Displaying notify '%s'\n", text);
-
-	transmit_response(d, req);
-}
-
-static void transmit_displaypromptstatus(struct skinny_device *d, const char *text, int t, int instance, int callid)
-{
-	struct skinny_req *req;
-
-	if (text == 0) {
-		if (!(req = req_alloc(sizeof(struct clear_prompt_message), CLEAR_PROMPT_MESSAGE)))
-			return;
-
-		req->data.clearpromptstatus.lineInstance = htolel(instance);
-		req->data.clearpromptstatus.callReference = htolel(callid);
-
-		if (skinnydebug)
-			ast_verb(1, "Clearing Prompt\n");
-	} else {
-		if (!(req = req_alloc(sizeof(struct display_prompt_status_message), DISPLAY_PROMPT_STATUS_MESSAGE)))
-			return;
-
-		ast_copy_string(req->data.displaypromptstatus.promptMessage, text, sizeof(req->data.displaypromptstatus.promptMessage));
-		req->data.displaypromptstatus.messageTimeout = htolel(t);
-		req->data.displaypromptstatus.lineInstance = htolel(instance);
-		req->data.displaypromptstatus.callReference = htolel(callid);
-
-		if (skinnydebug)
-			ast_verb(1, "Displaying Prompt Status '%s'\n", text);
-	}
-
-	transmit_response(d, req);
-}
-
-static void transmit_dialednumber(struct skinny_device *d, const char *text, int instance, int callid)
-{
-	struct skinny_req *req;
-
-	if (!(req = req_alloc(sizeof(struct dialed_number_message), DIALED_NUMBER_MESSAGE)))
-		return;
-
-	ast_copy_string(req->data.dialednumber.dialedNumber, text, sizeof(req->data.dialednumber.dialedNumber));
-	req->data.dialednumber.lineInstance = htolel(instance);
-	req->data.dialednumber.callReference = htolel(callid);
-
-	transmit_response(d, req);
-}
-
-static void transmit_closereceivechannel(struct skinny_device *d, struct skinny_subchannel *sub)
-{
-	struct skinny_req *req;
-
-	if (!(req = req_alloc(sizeof(struct close_receive_channel_message), CLOSE_RECEIVE_CHANNEL_MESSAGE)))
-		return;
-
-	req->data.closereceivechannel.conferenceId = htolel(0);
-	req->data.closereceivechannel.partyId = htolel(sub->callid);
-	transmit_response(d, req);
-}
-
-static void transmit_stopmediatransmission(struct skinny_device *d, struct skinny_subchannel *sub)
-{
-	struct skinny_req *req;
-
-	if (!(req = req_alloc(sizeof(struct stop_media_transmission_message), STOP_MEDIA_TRANSMISSION_MESSAGE)))
-		return;
-
-	req->data.stopmedia.conferenceId = htolel(0);
-	req->data.stopmedia.passThruPartyId = htolel(sub->callid);
-	transmit_response(d, req);
-}
-
-static void transmit_activatecallplane(struct skinny_device *d, struct skinny_line *l)
-{
-	struct skinny_req *req;
-
-	if (!(req = req_alloc(sizeof(struct activate_call_plane_message), ACTIVATE_CALL_PLANE_MESSAGE)))
-		return;
-
-	req->data.activatecallplane.lineInstance = htolel(l->instance);
-	transmit_response(d, req);
-}
-
-static void transmit_callstateonly(struct skinny_device *d, struct skinny_subchannel *sub, int state)
-{
-	struct skinny_req *req;
-
-	if (!(req = req_alloc(sizeof(struct call_state_message), CALL_STATE_MESSAGE)))
-		return;
-
-	req->data.callstate.callState = htolel(state);
-	req->data.callstate.lineInstance = htolel(sub->parent->instance);
-	req->data.callstate.callReference = htolel(sub->callid);
-	transmit_response(d, req);
-}
-
-static void transmit_callstate(struct skinny_device *d, int instance, int state, unsigned callid)
-{
-	struct skinny_req *req;
-
-	if (state == SKINNY_ONHOOK) {
-		if (!(req = req_alloc(sizeof(struct close_receive_channel_message), CLOSE_RECEIVE_CHANNEL_MESSAGE)))
-			return;
-
-		req->data.closereceivechannel.conferenceId = htolel(callid);
-		req->data.closereceivechannel.partyId = htolel(callid);
-		transmit_response(d, req);
-
-		if (!(req = req_alloc(sizeof(struct stop_media_transmission_message), STOP_MEDIA_TRANSMISSION_MESSAGE)))
-			return;
-
-		req->data.stopmedia.conferenceId = htolel(callid);
-		req->data.stopmedia.passThruPartyId = htolel(callid);
-		transmit_response(d, req);
-
-		transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
-
-		transmit_displaypromptstatus(d, NULL, 0, instance, callid);
-	}
-
-	if (!(req = req_alloc(sizeof(struct call_state_message), CALL_STATE_MESSAGE)))
-		return;
-
-	req->data.callstate.callState = htolel(state);
-	req->data.callstate.lineInstance = htolel(instance);
-	req->data.callstate.callReference = htolel(callid);
-	transmit_response(d, req);
-
-	if (state == SKINNY_ONHOOK) {
-		transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK);
-	}
-
-	if (state == SKINNY_OFFHOOK || state == SKINNY_ONHOOK) {
-		if (!(req = req_alloc(sizeof(struct activate_call_plane_message), ACTIVATE_CALL_PLANE_MESSAGE)))
-			return;
-
-		req->data.activatecallplane.lineInstance = htolel(instance);
-		transmit_response(d, req);
-	}
-}
-
-
-static void transmit_cfwdstate(struct skinny_device *d, struct skinny_line *l)
-{
-	struct skinny_req *req;
-	int anyon = 0;
-
-	if (!(req = req_alloc(sizeof(struct forward_stat_message), FORWARD_STAT_MESSAGE)))
-		return;
-
-	if (l->cfwdtype & SKINNY_CFWD_ALL) {
-		if (!ast_strlen_zero(l->call_forward_all)) {
-			ast_copy_string(req->data.forwardstat.fwdallnum, l->call_forward_all, sizeof(req->data.forwardstat.fwdallnum));
-			req->data.forwardstat.fwdall = htolel(1);
-			anyon++;
-		} else {
-			req->data.forwardstat.fwdall = htolel(0);
-		}
-	}
-	if (l->cfwdtype & SKINNY_CFWD_BUSY) {
-		if (!ast_strlen_zero(l->call_forward_busy)) {
-			ast_copy_string(req->data.forwardstat.fwdbusynum, l->call_forward_busy, sizeof(req->data.forwardstat.fwdbusynum));
-			req->data.forwardstat.fwdbusy = htolel(1);
-			anyon++;
-		} else {
-			req->data.forwardstat.fwdbusy = htolel(0);
-		}
-	}
-	if (l->cfwdtype & SKINNY_CFWD_NOANSWER) {
-		if (!ast_strlen_zero(l->call_forward_noanswer)) {
-			ast_copy_string(req->data.forwardstat.fwdnoanswernum, l->call_forward_noanswer, sizeof(req->data.forwardstat.fwdnoanswernum));
-			req->data.forwardstat.fwdnoanswer = htolel(1);

[... 7696 lines stripped ...]



More information about the asterisk-commits mailing list