Index: chan_mobile.c
===================================================================
--- chan_mobile.c	(revision 501)
+++ chan_mobile.c	(working copy)
@@ -125,7 +125,7 @@
 	AST_LIST_ENTRY(adapter_pvt) entry;
 };
 
-static AST_LIST_HEAD_STATIC(adapters, adapter_pvt);
+static AST_RWLIST_HEAD_STATIC(adapters, adapter_pvt);
 
 struct mbl_pvt {
 	struct ast_channel *owner;			/* Channel we belong to, possibly NULL */
@@ -173,7 +173,7 @@
 	AST_LIST_ENTRY(mbl_pvt) entry;
 };
 
-static AST_LIST_HEAD_STATIC(devices, mbl_pvt);
+static AST_RWLIST_HEAD_STATIC(devices, mbl_pvt);
 
 /* CLI stuff */
 static char *handle_cli_mobile_show_devices(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
@@ -269,13 +269,15 @@
 		return CLI_SHOWUSAGE;
 
 	ast_cli(a->fd, FORMAT1, "ID", "Address", "Group", "Adapter", "Connected", "State", "SMS");
-	AST_LIST_TRAVERSE(&devices, pvt, entry) {
+	AST_RWLIST_RDLOCK(&devices);
+	AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
 		ba2str(&pvt->addr, bdaddr);
 		snprintf(group, 5, "%d", pvt->group);
 		ast_cli(a->fd, FORMAT1, pvt->id, bdaddr, group, pvt->adapter->id, pvt->connected ? "Yes" : "No",
 			(pvt->state == MBL_STATE_IDLE) ? "Free" : (pvt->state < MBL_STATE_IDLE) ? "Init" : "Busy",
 			(pvt->has_sms) ? "Yes" : "No");
 	}
+	AST_RWLIST_UNLOCK(&devices);
 
 #undef FORMAT1
 
@@ -310,10 +312,12 @@
 		return CLI_SHOWUSAGE;
 
 	/* find a free adapter */
-	AST_LIST_TRAVERSE(&adapters, adapter, entry) {
+	AST_RWLIST_RDLOCK(&adapters);
+	AST_RWLIST_TRAVERSE(&adapters, adapter, entry) {
 		if (!adapter->inuse)
 			break;
 	}
+	AST_RWLIST_UNLOCK(&adapters);
 
 	if (!adapter) {
 		ast_cli(a->fd, "All Bluetooth adapters are in use at this time.\n");
@@ -370,10 +374,12 @@
 	if (a->argc != 4)
 		return CLI_SHOWUSAGE;
 
-	AST_LIST_TRAVERSE(&devices, pvt, entry) {
+	AST_RWLIST_RDLOCK(&devices);
+	AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
 		if (!strcmp(pvt->id, a->argv[2]))
 			break;
 	}
+	AST_RWLIST_UNLOCK(&devices);
 
 	if (!pvt || !pvt->connected) {
 		ast_cli(a->fd, "Device %s not found.\n", a->argv[2]);
@@ -417,10 +423,12 @@
 
 	stat = 1;
 
-	AST_LIST_TRAVERSE(&devices, pvt, entry) {
+	AST_RWLIST_RDLOCK(&devices);
+	AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
 		if (!strcmp(pvt->id, args.device))
 			break;
 	}
+	AST_RWLIST_UNLOCK(&devices);
 
 	if (pvt) {
 		if (pvt->connected)
@@ -470,10 +478,12 @@
 		return -1;
 	}
 
-	AST_LIST_TRAVERSE(&devices, pvt, entry) {
+	AST_RWLIST_RDLOCK(&devices);
+	AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
 		if (!strcmp(pvt->id, args.device))
 			break;
 	}
+	AST_RWLIST_UNLOCK(&devices);
 
 	if (!pvt) {
 		ast_log(LOG_ERROR,"Bluetooth device %s wasn't found in the list -- SMS will not be sent.\n", args.device);
@@ -583,7 +593,8 @@
 		*dest_num++ = 0x00;
 
 	/* Find requested device and make sure its connected. */
-	AST_LIST_TRAVERSE(&devices, pvt, entry) {
+	AST_RWLIST_RDLOCK(&devices);
+	AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
 		if (((dest_dev[0] == 'g') || (dest_dev[0] == 'G')) && ((dest_dev[1] >= '0') && (dest_dev[1] <= '9'))) {
 			group = atoi(dest_dev+1);
 			if (pvt->group == group)
@@ -592,6 +603,7 @@
 			break;
 		}
 	}
+	AST_RWLIST_UNLOCK(&devices);
 	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;
@@ -871,10 +883,12 @@
 
 	ast_debug(1, "Checking device state for device %s\n", device);
 
-	AST_LIST_TRAVERSE(&devices, pvt, entry) {
+	AST_RWLIST_RDLOCK(&devices);
+	AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
 		if (!strcmp(pvt->id, device))
 			break;
 	}
+	AST_RWLIST_UNLOCK(&devices);
 
 	if (pvt) {
 		if (pvt->connected) {
@@ -1773,9 +1787,11 @@
 	struct mbl_pvt *pvt;
 
 	for (;;) {
-		AST_LIST_TRAVERSE(&adapters, adapter, entry) {
+		AST_RWLIST_RDLOCK(&adapters);
+		AST_RWLIST_TRAVERSE(&adapters, adapter, entry) {
 			if (!adapter->inuse) {
-				AST_LIST_TRAVERSE(&devices, pvt, entry) {
+				AST_RWLIST_RDLOCK(&devices);
+				AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
 					if (!adapter->inuse && !pvt->connected && !strcmp(adapter->id, pvt->adapter->id)) {
 						if ((pvt->rfcomm_socket = rfcomm_connect(adapter->addr, pvt->addr, pvt->rfcomm_port)) > -1) {
 							pvt->state = 0;
@@ -1789,8 +1805,10 @@
 						}
 					}
 				}
+				AST_RWLIST_UNLOCK(&devices);
 			}
 		}
+		AST_RWLIST_UNLOCK(&adapters);
 		/* Go to sleep */
 		sleep(discovery_interval);
 	}
@@ -1845,10 +1863,12 @@
 			ast_debug(1, "Incoming Audio Connection from device %s MTU is %d\n", saddr, so.mtu);
 
 			pvt = NULL;
-			AST_LIST_TRAVERSE(&devices, pvt, entry) {
+			AST_RWLIST_RDLOCK(&devices);
+			AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
 				if (!bacmp(&pvt->addr, &addr.sco_bdaddr)) 
 					break;
 			}
+			AST_RWLIST_UNLOCK(&devices);
 			if (pvt) {
 				if (pvt->sco_socket != -1)
 					close(pvt->sco_socket);
@@ -1931,7 +1951,9 @@
 							hci_close_dev(adapter->hci_socket);
 							ast_free(adapter);
 						} else {
-							AST_LIST_INSERT_HEAD(&adapters, adapter, entry);
+							AST_RWLIST_WRLOCK(&adapters);
+							AST_RWLIST_INSERT_HEAD(&adapters, adapter, entry);
+							AST_RWLIST_UNLOCK(&adapters);
 							nadapters++;
 						}
 					}
@@ -1963,10 +1985,12 @@
 			nocallsetup = ast_variable_retrieve(cfg, cat, "nocallsetup");
 			if (!ast_strlen_zero(address) && !ast_strlen_zero(port) && !ast_strlen_zero(useadapter)) {
 				/* find the adapter */
-				AST_LIST_TRAVERSE(&adapters, adapter, entry) {
+				AST_RWLIST_RDLOCK(&adapters);
+				AST_RWLIST_TRAVERSE(&adapters, adapter, entry) {
 					if (!strcmp(adapter->id, useadapter))
 						break;
 				}
+				AST_RWLIST_UNLOCK(&adapters);
 				if (!adapter) {
 					ast_log(LOG_ERROR, "Device %s configured to use unknown adapter %s. It won't be enabled.\n", cat, useadapter);
 					break;
@@ -2002,7 +2026,9 @@
 					ast_dsp_set_features(pvt->dsp, DSP_FEATURE_DTMF_DETECT);
 					ast_dsp_digitmode(pvt->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
 					pvt->adapter = adapter;
-					AST_LIST_INSERT_HEAD(&devices, pvt, entry);
+					AST_RWLIST_WRLOCK(&devices);
+					AST_RWLIST_INSERT_HEAD(&devices, pvt, entry);
+					AST_RWLIST_UNLOCK(&devices);
 				}
 			} else {
 				ast_log(LOG_ERROR, "Device %s has no address/port/adapter configured. It won't be enabled.\n", cat);
@@ -2033,7 +2059,8 @@
 	}
 
 	/* Destroy the device list */
-	while ((pvt = AST_LIST_REMOVE_HEAD(&devices, entry))) {
+	AST_RWLIST_WRLOCK(&devices);
+	while ((pvt = AST_RWLIST_REMOVE_HEAD(&devices, entry))) {
 		if (pvt->monitor_thread != AST_PTHREADT_NULL) {
 			pthread_cancel(pvt->monitor_thread);
 			pthread_join(pvt->monitor_thread, NULL);
@@ -2054,12 +2081,15 @@
 		ast_dsp_free(pvt->dsp);
 		ast_free(pvt);
 	}
+	AST_RWLIST_UNLOCK(&devices);
 
 	/* Destroy the adapter list */
-	while ((adapter = AST_LIST_REMOVE_HEAD(&adapters, entry))) {
+	AST_RWLIST_WRLOCK(&adapters);
+	while ((adapter = AST_RWLIST_REMOVE_HEAD(&adapters, entry))) {
 		hci_close_dev(adapter->hci_socket);
 		ast_free(adapter);
 	}
+	AST_RWLIST_UNLOCK(&adapters);
 
 	if (sdp_session)
 		sdp_close(sdp_session);
