[svn-commits] dcb: trunk r438 - /trunk/chan_mobile.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Sep 6 05:41:21 CDT 2007


Author: dcb
Date: Thu Sep  6 05:41:21 2007
New Revision: 438

URL: http://svn.digium.com/view/asterisk-addons?view=rev&rev=438
Log:
code cleanup and formatting changes

Modified:
    trunk/chan_mobile.c

Modified: trunk/chan_mobile.c
URL: http://svn.digium.com/view/asterisk-addons/trunk/chan_mobile.c?view=diff&rev=438&r1=437&r2=438
==============================================================================
--- trunk/chan_mobile.c (original)
+++ trunk/chan_mobile.c Thu Sep  6 05:41:21 2007
@@ -19,7 +19,7 @@
 /*! \file
  *
  * \brief Bluetooth Mobile Device channel driver
- * 
+ *
  * \author Dave Bowerman <david.bowerman at gmail.com>
  *
  * \ingroup channel_drivers
@@ -74,7 +74,8 @@
 
 static int prefformat = AST_FORMAT_SLINEAR;
 
-static int discovery_interval = 60;	/* The device discovery interval, default 60 seconds. */
+static int discovery_interval = 60;			/* The device discovery interval, default 60 seconds. */
+static pthread_t discovery_thread = AST_PTHREADT_NULL;	/* The discovery thread */
 static sdp_session_t *sdp_session;
 
 enum mbl_type {
@@ -107,11 +108,11 @@
 };
 
 struct adapter_pvt {
-	int dev_id;						/* device id */
+	int dev_id;					/* device id */
 	int hci_socket;					/* device descriptor */
 	char id[31];					/* the 'name' from mobile.conf */
 	bdaddr_t addr;					/* adddress of adapter */
-	char inuse;						/* are we in use ? */
+	char inuse;					/* are we in use ? */
 	int sco_socket;
 	AST_LIST_ENTRY(adapter_pvt) entry;
 };
@@ -119,28 +120,28 @@
 static AST_LIST_HEAD_STATIC(adapters, adapter_pvt);
 
 struct mbl_pvt {
-	struct ast_channel *owner;		/* Channel we belong to, possibly NULL */
-	struct ast_frame fr;			/* "null" frame */
+	struct ast_channel *owner;			/* Channel we belong to, possibly NULL */
+	struct ast_frame fr;				/* "null" frame */
 	enum mbl_type type;				/* Phone or Headset */
 	char id[31];					/* The id from mobile.conf */
-	int group;						/* group number for group dialling */
+	int group;					/* group number for group dialling */
 	bdaddr_t addr;					/* address of device */
-	struct adapter_pvt *adapter;	/* the adapter we use */
-	char context[AST_MAX_CONTEXT];	/* the context for incoming calls */
+	struct adapter_pvt *adapter;			/* the adapter we use */
+	char context[AST_MAX_CONTEXT];			/* the context for incoming calls */
 	char connected;					/* is it connected? */
 	int rfcomm_port;				/* rfcomm port number */
 	int rfcomm_socket;				/* rfcomm socket descriptor */
 	char rfcomm_buf[256];
 	int sco_socket;					/* sco socket descriptor */
-	pthread_t sco_listener_thread;	/* inbound sco listener for this device */	
-	enum mbl_state state;			/* monitor thread current state */
-	pthread_t monitor_thread;		/* monitor thread handle */
+	pthread_t sco_listener_thread;			/* inbound sco listener for this device */	
+	enum mbl_state state;				/* monitor thread current state */
+	pthread_t monitor_thread;			/* monitor thread handle */
 	char sco_in_buf[48 + AST_FRIENDLY_OFFSET];
 	char sco_save_buf[48];
 	int sco_save_len;	
-	char dial_number[AST_MAX_EXTENSION];	/* number for the monitor thread to dial */
+	char dial_number[AST_MAX_EXTENSION];		/* number for the monitor thread to dial */
 	int dial_timeout;
-	char ciev_call_0[4];			/* dynamically built reponse strings */
+	char ciev_call_0[4];				/* dynamically built reponse strings */
 	char ciev_call_1[4];
 	char ciev_callsetup_0[4];
 	char ciev_callsetup_1[4];
@@ -160,9 +161,6 @@
 
 static AST_LIST_HEAD_STATIC(devices, mbl_pvt);
 
-/* The discovery thread */
-static pthread_t discovery_thread = AST_PTHREADT_NULL;
-
 /* CLI stuff */
 static const char show_usage[] =
 "Usage: mobile show devices\n" 
@@ -203,6 +201,7 @@
 "  Dest - destination\n"
 "  Message - text of the message\n";
 
+static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, char *cid_num);
 static struct ast_channel *mbl_request(const char *type, int format, void *data, int *cause);
 static int mbl_call(struct ast_channel *ast, char *dest, int timeout);
 static int mbl_hangup(struct ast_channel *ast);
@@ -213,14 +212,16 @@
 static int mbl_write(struct ast_channel *ast, struct ast_frame *frame);
 static int mbl_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
 static int mbl_devicestate(void *data);
-static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, char *cid_num);
-
+
+static int rfcomm_connect(bdaddr_t src, bdaddr_t dst, int remote_channel);
 static int rfcomm_write(struct mbl_pvt *pvt, char *buf);
 static int rfcomm_read(struct mbl_pvt *pvt, char *buf, char flush, int timeout);
+
 static int sco_connect(bdaddr_t src, bdaddr_t dst);
 static int sco_write(int s, char *buf, int len);
 static int sco_read(int s, char *buf, int len);
 static int sco_set_options(int s);
+
 static void *do_sco_listen(void *data);
 static int sdp_search(char *addr, int profile);
 
@@ -239,6 +240,12 @@
 	.fixup = mbl_fixup,
 	.devicestate = mbl_devicestate
 };
+
+/*
+
+	CLI Commands implementation
+
+*/
 
 static int do_show_devices(int fd, int argc, char **argv)
 {
@@ -341,6 +348,12 @@
 
 }
 
+/*
+
+	Dialplan applications implementation
+
+*/
+
 static int mbl_status_exec(struct ast_channel *ast, void *data)
 {
 
@@ -409,7 +422,6 @@
 		return -1;
 	}
 	
-
 	AST_LIST_TRAVERSE(&devices, pvt, entry) {
 		if (!strcmp(pvt->id, device))
 			break;
@@ -444,346 +456,11 @@
 
 }
 
-static struct ast_channel *mbl_request(const char *type, int format, void *data, int *cause)
-{
-
-	struct ast_channel *chn = NULL;
-	struct mbl_pvt *pvt;
-	char *dest_dev = NULL;
-	char *dest_num = NULL;
-	int oldformat, group;
-	
-	if (!data) {
-		ast_log(LOG_WARNING, "Channel requested with no data\n");
-		*cause = AST_CAUSE_INCOMPATIBLE_DESTINATION;
-		return NULL;
-	}
-
-	oldformat = format;
-	format &= (AST_FORMAT_SLINEAR);
-	if (!format) {
-		ast_log(LOG_WARNING, "Asked to get a channel of unsupported format '%d'\n", oldformat);
-		*cause = AST_CAUSE_FACILITY_NOT_IMPLEMENTED;
-		return NULL;
-	}
-
-	dest_dev = ast_strdupa((char *)data);
-
-	dest_num = strchr(dest_dev, '/');
-	if (dest_num)
-		*dest_num++ = 0x00;
-
-	/* Find requested device and make sure its connected. */
-	AST_LIST_TRAVERSE(&devices, pvt, entry) {
-		if ((dest_dev[0] == 'g') || (dest_dev[0] == 'G')) {
-			group = atoi(dest_dev+1);
-			if (pvt->group == group)
-				break;
-		} else if (!strcmp(pvt->id, dest_dev)) {
-			break;
-		}
-	}
-	if (!pvt || !pvt->connected || pvt->owner) {
-		ast_log(LOG_WARNING, "Request to call on device %s which is not connected / already in use.\n", dest_dev);
-		*cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
-		return NULL;
-	}
-
-	if ((pvt->type == MBL_TYPE_PHONE) && !dest_num) {
-		ast_log(LOG_WARNING, "Cant determine destination number.\n");
-		*cause = AST_CAUSE_INCOMPATIBLE_DESTINATION;
-		return NULL;
-	}
-
-	chn = mbl_new(AST_STATE_DOWN, pvt, NULL);
-	if (!chn) {
-		ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
-		*cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
-		return NULL;
-	}
-
-	return chn;
-
-}
-
-static int mbl_call(struct ast_channel *ast, char *dest, int timeout)
-{
-
-	struct mbl_pvt *pvt;
-	char *dest_dev = NULL;
-	char *dest_num = NULL;
-	
-	dest_dev = ast_strdupa((char *)dest);
-
-	pvt = ast->tech_pvt;
-	ast_mutex_lock(&pvt->owner->lock);
-
-	if (pvt->type == MBL_TYPE_PHONE) {
-		dest_num = strchr(dest_dev, '/');
-		if (!dest_num) {
-			ast_log(LOG_WARNING, "Cant determine destination number.\n");
-			return -1;
-		}
-		*dest_num++ = 0x00;
-	}
-
-	if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
-		ast_log(LOG_WARNING, "mbl_call called on %s, neither down nor reserved\n", ast->name);
-		ast_mutex_unlock(&pvt->owner->lock);
-		return -1;
-	}
-
-	ast_debug(1, "Calling %s on %s\n", dest, ast->name);
-
-	if (pvt->type == MBL_TYPE_PHONE) {
-		ast_copy_string(pvt->dial_number, dest_num, sizeof(pvt->dial_number));
-		pvt->state = MBL_STATE_DIAL;
-		pvt->dial_timeout = (timeout == 0) ? 30 : timeout;
-	} else {
-		pvt->state = MBL_STATE_RING;
-	}
-
-	ast_mutex_unlock(&pvt->owner->lock);
-	
-	return 0;
-
-}
-
-static int mbl_hangup(struct ast_channel *ast)
-{
-
-	struct mbl_pvt *pvt;
-	
-	if (!ast->tech_pvt) {
-		ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
-		return 0;
-	}
-	pvt = ast->tech_pvt;
-
-	ast_debug(1, "Hanging up device %s.\n", pvt->id);
-
-	ast_channel_lock(ast);
-	ast_channel_set_fd(ast, 0, -1);
-	ast_channel_unlock(ast);
-
-	if (pvt->type == MBL_TYPE_HEADSET && pvt->sco_socket != -1) {
-		close(pvt->sco_socket);
-		pvt->sco_socket = -1;
-	}
-
-	if ((pvt->state == MBL_STATE_INCOMING || pvt->state == MBL_STATE_OUTGOING || pvt->state == MBL_STATE_DIAL1 || pvt->state == MBL_STATE_RING3) && pvt->type == MBL_TYPE_PHONE) {
-		rfcomm_write(pvt, "AT+CHUP\r");
-		pvt->state = MBL_STATE_HANGUP;
-		pvt->hangup_count = 0;
-	} else
-		pvt->state = MBL_STATE_IDLE;
-
-	pvt->owner = NULL;
-	ast->tech_pvt = NULL;
-	ast_setstate(ast, AST_STATE_DOWN);
-
-	return 0;
-
-}
-
-static int mbl_answer(struct ast_channel *ast)
-{
-
-	struct mbl_pvt *pvt;
-	
-	pvt = ast->tech_pvt;
-
-	rfcomm_write(pvt, "ATA\r");
-
-	ast_setstate(ast, AST_STATE_UP);
-
-	pvt->sent_answer = 1;
-
-	return 0;
-
-}
-
-static int mbl_digit_begin(struct ast_channel *chan, char digit)
-{
-
-	return 0;
-
-}
-
-static int mbl_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
-{
-
-	struct mbl_pvt *pvt;
-	char buf[11];
-	
-	pvt = ast->tech_pvt;
-
-	if (pvt->type == MBL_TYPE_HEADSET)
-		return 0;
-
-	ast_debug(1, "Dialed %c\n", digit);
-
-	switch(digit) {
-	case '0':
-	case '1':
-	case '2':
-	case '3':
-	case '4':
-	case '5':
-	case '6':
-	case '7':
-	case '8':
-	case '9':
-	case '*':
-	case '#':
-		sprintf(buf, "AT+VTS=%c\r", digit);
-		rfcomm_write(pvt, buf);
-		break;
-	default:
-		ast_log(LOG_WARNING, "Unknown digit '%c'\n", digit);
-		return -1;
-	}
-
-	return 0;
-
-}
-
 /*
 
-	The SCO protocol basically delivers audio in 48 byte 'frames' in slin format.
-	Here we just package these into an ast_frame and return them.
-	The SCO connection from the device to Asterisk happens asynchronously, so it is feasible
-	that Asterisk will call mbl_read() before the device has connected. In that case we just return
-	a null frame.
+	Channel Driver callbacks
 
 */
-
-static struct ast_frame *mbl_read(struct ast_channel *ast)
-{
-
-	struct mbl_pvt *pvt = ast->tech_pvt;
-	struct ast_frame *f;
-
-	if (!pvt->owner) {
-		return &ast_null_frame;
-	}
-
-	if (pvt->state == MBL_STATE_HANGUP) {
-		return &ast_null_frame;
-	}
-
-	if (pvt->sco_socket == -1) {
-		return &ast_null_frame;
-	}
-
-	pvt->fr.frametype = AST_FRAME_VOICE;
-	pvt->fr.subclass = AST_FORMAT_SLINEAR;
-	pvt->fr.data = pvt->sco_in_buf + AST_FRIENDLY_OFFSET;
-
-	if (sco_read(pvt->sco_socket, pvt->sco_in_buf + AST_FRIENDLY_OFFSET, 48)) {
-		if ((pvt->type == MBL_TYPE_PHONE) && (pvt->skip_frames == 0)) {
-			f = ast_dsp_process(0, pvt->dsp, &pvt->fr);
-			if (f && (f->frametype == AST_FRAME_DTMF_END)) {
-				pvt->fr.frametype = AST_FRAME_DTMF_END;
-				pvt->fr.subclass = f->subclass;
-				pvt->skip_frames = pvt->dtmf_skip;
-			}
-		} else {
-			pvt->skip_frames--;
-		}
-		return &pvt->fr;
-	}
-
-	return &ast_null_frame;
-
-}
-
-/*
-
-	We need to deliver 48 byte 'frames' of slin format audio to the device.
-	mbl_write() handles this by buffering short frames until the next time we are called.
-
-*/
-
-static int mbl_write(struct ast_channel *ast, struct ast_frame *frame)
-{
-
-	struct mbl_pvt *pvt = ast->tech_pvt;
-	int num_frames, i, sco_need = 0;
-	char *pfr;
-		
-	if (frame->frametype != AST_FRAME_VOICE) {
-		return 0;
-	}
-	if (pvt->sco_socket == -1) {
-		return 0;
-	}
-	if (ast->_state != AST_STATE_UP) {
-		return 0;
-	}
-	if (pvt->state == MBL_STATE_HANGUP) {
-		return 0;
-	}
-	
-	if (pvt->sco_save_len > 0) {
-		sco_need = 48 - pvt->sco_save_len;
-		memcpy(pvt->sco_save_buf + pvt->sco_save_len, frame->data, sco_need);
-		sco_write(pvt->sco_socket, pvt->sco_save_buf, 48);
-	}
-	num_frames = (frame->datalen - sco_need) / 48;
-	pfr = frame->data + sco_need; 
-	for (i=0; i<num_frames; i++) {
-		sco_write(pvt->sco_socket, pfr, 48);
-		pfr += 48;
-	}
-	pvt->sco_save_len = (frame->datalen - sco_need) - (num_frames * 48);
-	if (pvt->sco_save_len > 0) {
-		memcpy(pvt->sco_save_buf, pfr, pvt->sco_save_len);
-	}
-	return 0;
-
-}
-
-static int mbl_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
-{
-
-	struct mbl_pvt *pvt = oldchan->tech_pvt;
-	
-	if (pvt && pvt->owner == oldchan)
-		pvt->owner = newchan;
-
-	return 0;
-
-}
-
-static int mbl_devicestate(void *data)
-{
-
-	char *device;
-	int res = AST_DEVICE_INVALID;
-	struct mbl_pvt *pvt;
-	
-	device = ast_strdupa(S_OR(data, ""));
-
-	ast_debug(1, "Checking device state for device %s\n", device);
-
-	AST_LIST_TRAVERSE(&devices, pvt, entry) {
-		if (!strcmp(pvt->id, device))
-			break;
-	}
-
-	if (pvt) {
-		if (pvt->connected) {
-			if (pvt->owner)
-				res = AST_DEVICE_INUSE;
-			else
-				res = AST_DEVICE_NOT_INUSE;
-		}
-	}
-
-	return res;
-
-}
 
 static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, char *cid_num)
 {
@@ -818,13 +495,342 @@
 			chn->rings = 1;
 		ast_string_field_set(chn, language, "en");
 		pvt->owner = chn;
-
 		return chn;
 	}
 
 	return NULL;
 
 }
+
+static struct ast_channel *mbl_request(const char *type, int format, void *data, int *cause)
+{
+
+	struct ast_channel *chn = NULL;
+	struct mbl_pvt *pvt;
+	char *dest_dev = NULL;
+	char *dest_num = NULL;
+	int oldformat, group;
+	
+	if (!data) {
+		ast_log(LOG_WARNING, "Channel requested with no data\n");
+		*cause = AST_CAUSE_INCOMPATIBLE_DESTINATION;
+		return NULL;
+	}
+
+	oldformat = format;
+	format &= (AST_FORMAT_SLINEAR);
+	if (!format) {
+		ast_log(LOG_WARNING, "Asked to get a channel of unsupported format '%d'\n", oldformat);
+		*cause = AST_CAUSE_FACILITY_NOT_IMPLEMENTED;
+		return NULL;
+	}
+
+	dest_dev = ast_strdupa((char *)data);
+
+	dest_num = strchr(dest_dev, '/');
+	if (dest_num)
+		*dest_num++ = 0x00;
+
+	/* Find requested device and make sure its connected. */
+	AST_LIST_TRAVERSE(&devices, pvt, entry) {
+		if ((dest_dev[0] == 'g') || (dest_dev[0] == 'G')) {
+			group = atoi(dest_dev+1);
+			if (pvt->group == group)
+				break;
+		} else if (!strcmp(pvt->id, dest_dev)) {
+			break;
+		}
+	}
+	if (!pvt || !pvt->connected || pvt->owner) {
+		ast_log(LOG_WARNING, "Request to call on device %s which is not connected / already in use.\n", dest_dev);
+		*cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
+		return NULL;
+	}
+
+	if ((pvt->type == MBL_TYPE_PHONE) && !dest_num) {
+		ast_log(LOG_WARNING, "Cant determine destination number.\n");
+		*cause = AST_CAUSE_INCOMPATIBLE_DESTINATION;
+		return NULL;
+	}
+
+	chn = mbl_new(AST_STATE_DOWN, pvt, NULL);
+	if (!chn) {
+		ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
+		*cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
+		return NULL;
+	}
+
+	return chn;
+
+}
+
+static int mbl_call(struct ast_channel *ast, char *dest, int timeout)
+{
+
+	struct mbl_pvt *pvt;
+	char *dest_dev = NULL;
+	char *dest_num = NULL;
+	
+	dest_dev = ast_strdupa((char *)dest);
+
+	pvt = ast->tech_pvt;
+	ast_mutex_lock(&pvt->owner->lock);
+
+	if (pvt->type == MBL_TYPE_PHONE) {
+		dest_num = strchr(dest_dev, '/');
+		if (!dest_num) {
+			ast_log(LOG_WARNING, "Cant determine destination number.\n");
+			return -1;
+		}
+		*dest_num++ = 0x00;
+	}
+
+	if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
+		ast_log(LOG_WARNING, "mbl_call called on %s, neither down nor reserved\n", ast->name);
+		ast_mutex_unlock(&pvt->owner->lock);
+		return -1;
+	}
+
+	ast_debug(1, "Calling %s on %s\n", dest, ast->name);
+
+	if (pvt->type == MBL_TYPE_PHONE) {
+		ast_copy_string(pvt->dial_number, dest_num, sizeof(pvt->dial_number));
+		pvt->state = MBL_STATE_DIAL;
+		pvt->dial_timeout = (timeout == 0) ? 30 : timeout;
+	} else {
+		pvt->state = MBL_STATE_RING;
+	}
+
+	ast_mutex_unlock(&pvt->owner->lock);
+	
+	return 0;
+
+}
+
+static int mbl_hangup(struct ast_channel *ast)
+{
+
+	struct mbl_pvt *pvt;
+	
+	if (!ast->tech_pvt) {
+		ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
+		return 0;
+	}
+	pvt = ast->tech_pvt;
+
+	ast_debug(1, "Hanging up device %s.\n", pvt->id);
+
+	ast_channel_lock(ast);
+	ast_channel_set_fd(ast, 0, -1);
+	ast_channel_unlock(ast);
+
+	if (pvt->type == MBL_TYPE_HEADSET && pvt->sco_socket != -1) {
+		close(pvt->sco_socket);
+		pvt->sco_socket = -1;
+	}
+
+	if ((pvt->state == MBL_STATE_INCOMING || pvt->state == MBL_STATE_OUTGOING || pvt->state == MBL_STATE_DIAL1 || pvt->state == MBL_STATE_RING3) && pvt->type == MBL_TYPE_PHONE) {
+		rfcomm_write(pvt, "AT+CHUP\r");
+		pvt->state = MBL_STATE_HANGUP;
+		pvt->hangup_count = 0;
+	} else
+		pvt->state = MBL_STATE_IDLE;
+
+	pvt->owner = NULL;
+	ast->tech_pvt = NULL;
+	ast_setstate(ast, AST_STATE_DOWN);
+
+	return 0;
+
+}
+
+static int mbl_answer(struct ast_channel *ast)
+{
+
+	struct mbl_pvt *pvt;
+	
+	pvt = ast->tech_pvt;
+
+	rfcomm_write(pvt, "ATA\r");
+
+	ast_setstate(ast, AST_STATE_UP);
+
+	pvt->sent_answer = 1;
+
+	return 0;
+
+}
+
+static int mbl_digit_begin(struct ast_channel *chan, char digit)
+{
+
+	return 0;
+
+}
+
+static int mbl_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
+{
+
+	struct mbl_pvt *pvt;
+	char buf[11];
+	
+	pvt = ast->tech_pvt;
+
+	if (pvt->type == MBL_TYPE_HEADSET)
+		return 0;
+
+	ast_debug(1, "Dialed %c\n", digit);
+
+	switch(digit) {
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+	case '*':
+	case '#':
+		sprintf(buf, "AT+VTS=%c\r", digit);
+		rfcomm_write(pvt, buf);
+		break;
+	default:
+		ast_log(LOG_WARNING, "Unknown digit '%c'\n", digit);
+		return -1;
+	}
+
+	return 0;
+
+}
+
+static struct ast_frame *mbl_read(struct ast_channel *ast)
+{
+
+	struct mbl_pvt *pvt = ast->tech_pvt;
+	struct ast_frame *f;
+
+	if (!pvt->owner) {
+		return &ast_null_frame;
+	}
+
+	if (pvt->state == MBL_STATE_HANGUP) {
+		return &ast_null_frame;
+	}
+
+	if (pvt->sco_socket == -1) {
+		return &ast_null_frame;
+	}
+
+	pvt->fr.frametype = AST_FRAME_VOICE;
+	pvt->fr.subclass = AST_FORMAT_SLINEAR;
+	pvt->fr.data = pvt->sco_in_buf + AST_FRIENDLY_OFFSET;
+
+	if (sco_read(pvt->sco_socket, pvt->sco_in_buf + AST_FRIENDLY_OFFSET, 48)) {
+		if ((pvt->type == MBL_TYPE_PHONE) && (pvt->skip_frames == 0)) {
+			f = ast_dsp_process(0, pvt->dsp, &pvt->fr);
+			if (f && (f->frametype == AST_FRAME_DTMF_END)) {
+				pvt->fr.frametype = AST_FRAME_DTMF_END;
+				pvt->fr.subclass = f->subclass;
+				pvt->skip_frames = pvt->dtmf_skip;
+			}
+		} else {
+			pvt->skip_frames--;
+		}
+		return &pvt->fr;
+	}
+
+	return &ast_null_frame;
+
+}
+
+static int mbl_write(struct ast_channel *ast, struct ast_frame *frame)
+{
+
+	struct mbl_pvt *pvt = ast->tech_pvt;
+	int num_frames, i, sco_need = 0;
+	char *pfr;
+		
+	if (frame->frametype != AST_FRAME_VOICE) {
+		return 0;
+	}
+	if (pvt->sco_socket == -1) {
+		return 0;
+	}
+	if (ast->_state != AST_STATE_UP) {
+		return 0;
+	}
+	if (pvt->state == MBL_STATE_HANGUP) {
+		return 0;
+	}
+	
+	if (pvt->sco_save_len > 0) {
+		sco_need = 48 - pvt->sco_save_len;
+		memcpy(pvt->sco_save_buf + pvt->sco_save_len, frame->data, sco_need);
+		sco_write(pvt->sco_socket, pvt->sco_save_buf, 48);
+	}
+	num_frames = (frame->datalen - sco_need) / 48;
+	pfr = frame->data + sco_need; 
+	for (i=0; i<num_frames; i++) {
+		sco_write(pvt->sco_socket, pfr, 48);
+		pfr += 48;
+	}
+	pvt->sco_save_len = (frame->datalen - sco_need) - (num_frames * 48);
+	if (pvt->sco_save_len > 0) {
+		memcpy(pvt->sco_save_buf, pfr, pvt->sco_save_len);
+	}
+	return 0;
+
+}
+
+static int mbl_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
+{
+
+	struct mbl_pvt *pvt = oldchan->tech_pvt;
+	
+	if (pvt && pvt->owner == oldchan)
+		pvt->owner = newchan;
+
+	return 0;
+
+}
+
+static int mbl_devicestate(void *data)
+{
+
+	char *device;
+	int res = AST_DEVICE_INVALID;
+	struct mbl_pvt *pvt;
+	
+	device = ast_strdupa(S_OR(data, ""));
+
+	ast_debug(1, "Checking device state for device %s\n", device);
+
+	AST_LIST_TRAVERSE(&devices, pvt, entry) {
+		if (!strcmp(pvt->id, device))
+			break;
+	}
+
+	if (pvt) {
+		if (pvt->connected) {
+			if (pvt->owner)
+				res = AST_DEVICE_INUSE;
+			else
+				res = AST_DEVICE_NOT_INUSE;
+		}
+	}
+
+	return res;
+
+}
+
+/*
+
+	rfcomm helpers
+
+*/
 
 static int rfcomm_connect(bdaddr_t src, bdaddr_t dst, int remote_channel) {
 
@@ -837,10 +843,10 @@
 	}
 
 	memset(&addr, 0, sizeof(addr));
-    addr.rc_family = AF_BLUETOOTH;
-    bacpy(&addr.rc_bdaddr, &src);
-    addr.rc_channel = (uint8_t) 1;
-    if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+	addr.rc_family = AF_BLUETOOTH;
+	bacpy(&addr.rc_bdaddr, &src);
+	addr.rc_channel = (uint8_t) 1;
+	if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
 		ast_debug(1, "bind() failed (%d).\n", errno);
 		close(s);
 		return -1;
@@ -949,6 +955,12 @@
 
 }
 
+/*
+
+	sco helpers
+
+*/
+
 static int sco_connect(bdaddr_t src, bdaddr_t dst)
 {
 
@@ -961,9 +973,9 @@
 	}
 
 	memset(&addr, 0, sizeof(addr));
-    addr.sco_family = AF_BLUETOOTH;
-    bacpy(&addr.sco_bdaddr, &src);
-    if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+	addr.sco_family = AF_BLUETOOTH;
+	bacpy(&addr.sco_bdaddr, &src);
+	if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
 		ast_debug(1, "bind() failed (%d).\n", errno);
 		close(s);
 		return -1;
@@ -982,12 +994,6 @@
 	return s;
 
 }
-
-/*
-
-	sco_write()
-	
-*/
 
 static int sco_write(int s, char *buf, int len)
 {
@@ -1016,12 +1022,6 @@
 	return 1;
 
 }
-
-/*
-
-	sco_read()
-	
-*/
 
 static int sco_read(int s, char *buf, int len)
 {
@@ -1041,12 +1041,6 @@
 	
 }
 
-/*
-
-	sco_set_options()
-	
-*/
-
 static int sco_set_options(int s)
 {
 
@@ -1070,8 +1064,7 @@
 
 /*
 
-	sdp_search() performs a service discovery on the given device to determine whether
-	or not it supports the Handsfree Profile.
+	sdp helpers
 
 */
 
@@ -1115,7 +1108,6 @@
 	} else
 		ast_debug(1, "sdp_service_search_attr_req() failed on device %s.\n", addr);
 
-
 	sdp_list_free(search_list, 0);
 	sdp_list_free(attrid_list, 0);
 	sdp_close(session);
@@ -1123,16 +1115,6 @@
 	return port;
 
 }
-
-/*
-
-	sdp_register()
-
-	Register GENERIC_AUDIO & HEADSET with the SDP daemon on the Asterisk Box.
-	This assists connections to phones/pda's with dud bluetooth stacks like the IMate Jasjam
-	and some Nokia's
-
-*/
 
 static sdp_session_t *sdp_register(void)
 {
@@ -1198,11 +1180,7 @@
 
 /*
 
-	Phone Monitor Thread
-
-	This thread is spun once a phone device is discovered and considered capable of being used, i.e. supports Handsfree Profile,
-	and its configured in mobile.conf.
-	The thread lives for the lifetime of the bluetooth connection, and handles the 'control' side of all calls.
+	Thread routines
 
 */
 
@@ -1247,7 +1225,7 @@
 			case MBL_STATE_INIT:
 				if (strstr(buf, "+BRSF:")) {
 					brsf = 1;
-				} else if (strstr(buf, "ERROR") && !nsmode) { /* Hmmm, Non-Standard Phone, just continue */
+				} else if (strstr(buf, "ERROR") && !nsmode) {	/* Hmmm, Non-Standard Phone, just continue */
 					rfcomm_write(pvt, "AT+CIND=?\r");
 					pvt->state++;
 					nsmode = 1;
@@ -1315,7 +1293,7 @@
 				}
 				break;
 			case MBL_STATE_INIT5:
-				if (strstr(buf, "ERROR")) { /* No SMS Support ! */
+				if (strstr(buf, "ERROR")) {	/* No SMS Support ! */
 					pvt->state = MBL_STATE_PREIDLE;
 				} else if (strstr(buf, "OK")) {
 					rfcomm_write(pvt, "AT+CNMI=2,1,0,1,0\r");
@@ -1323,7 +1301,7 @@
 				}
 				break;
 			case MBL_STATE_INIT6:
-				if (strstr(buf, "OK")) { /* We have SMS Support */
+				if (strstr(buf, "OK")) {	/* We have SMS Support */
 					pvt->has_sms = 1;
 					pvt->state = MBL_STATE_PREIDLE;
 				} else if (strstr(buf, "ERROR")) {
@@ -1340,8 +1318,8 @@
 					pvt->state = MBL_STATE_RING;
 				} else if (strstr(buf, "+CIEV:")) {
 					if (strstr(buf, pvt->ciev_callsetup_3)) {	/* User has dialed out on handset */
-						monitor = 0;							/* We disconnect now, as he is    */
-					}											/* probably leaving BT range...   */
+						monitor = 0;				/* We disconnect now, as he is    */
+					}						/* probably leaving BT range...   */
 				}
 				break;
 			case MBL_STATE_DIAL: /* Nothing handled here, we need to wait for a timeout */
@@ -1560,16 +1538,6 @@
 
 }
 
-/*
-
-	Headset Monitor Thread
-
-	This thread is spun once a headset device is discovered and considered capable of being used, i.e. supports Headset Profile,
-	and its configured in mobile.conf.
-	The thread lives for the lifetime of the bluetooth connection, and handles the 'control' side of all calls.
-
-*/
-
 static void *do_monitor_headset(void *data)
 {
 
@@ -1678,18 +1646,6 @@
 
 }
 
-/*
-
-	Device Discovery Thread.
-
-	This thread wakes every 'discovery_interval' seconds and trys to connect to
-	those configured devices which are not connected. This saves the user from having
-	to manually connect his/her cell phone to the asterisk box. Once a successful
-	connection is made, a monitor thread is spun on the device which lives for the
-	lifetime of the connection.
-
-*/
-
 static void *do_discovery(void *data)
 {
 
@@ -1721,16 +1677,6 @@
 	return NULL;
 }
 
-/*
-
-	This thread listens for incoming sco connections.
-	Although the Bluetooth Handsfree Profile Specification says that either end may initiate the audio connection,
-	in practice some devices (LG TU500) get upset unless they initiate the connection.
-	We leave all sco initiation to the device.
-	On an inbound sco connection, we need to find the appropriate device, and set the channel fd accordingly.
-
-*/
-
 static void *do_sco_listen(void *data)
 {
 
@@ -1767,10 +1713,11 @@
 		return NULL;
 	}
 	while (1) {
+		ast_debug(1, "About to accept() socket.\n");
 		addrlen = sizeof(struct sockaddr_sco);
-		ast_log(LOG_NOTICE, "About to accept the sco_socket...\n");
 		if ((ns = accept(adapter->sco_socket, (struct sockaddr *)&addr, &addrlen)) > -1) {
-			ast_log(LOG_NOTICE, "sco_socket returns %d...\n",ns);
+
+			ast_debug(1, "accept()ed socket.\n");
 
 			sco_set_options(ns);
 			
@@ -1786,7 +1733,6 @@
 					break;
 			}
 			if (pvt) {
-				ast_log(LOG_NOTICE,"about to close the pvt-sco_socket and set it ns\n");
 				if (pvt->sco_socket != -1)
 					close(pvt->sco_socket);
 				pvt->sco_socket = ns;
@@ -1797,13 +1743,20 @@
 				}
 			} else
 				ast_debug(1, "Could not find device for incoming Audio Connection.\n");
+		} else {
+			 ast_log(LOG_ERROR, "accept() failed %d\n", errno);
 		}
-		else ast_log(LOG_NOTICE, "Accept got a -1....");
 	}
 
 	return NULL;
 
 }
+
+/*
+
+	Module
+
+*/
 
 static int mbl_load_config(void)
 {




More information about the svn-commits mailing list