diff --git a/src/host/layer23/configure.ac b/src/host/layer23/configure.ac
index 1be98ee..e1c718e 100644
--- a/src/host/layer23/configure.ac
+++ b/src/host/layer23/configure.ac
@@ -15,6 +15,7 @@ AC_PROG_RANLIB
 dnl checks for libraries
 PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore)
 PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty)
+AC_CHECK_LIB(gps, gps_open, CFLAGS+=" -D_USE_GPSD" LDFLAGS+=" -lgps",,)
 
 dnl checks for header files
 AC_HEADER_STDC
diff --git a/src/host/layer23/include/osmocom/bb/common/gps.h b/src/host/layer23/include/osmocom/bb/common/gps.h
index e45cbc5..b7500db 100644
--- a/src/host/layer23/include/osmocom/bb/common/gps.h
+++ b/src/host/layer23/include/osmocom/bb/common/gps.h
@@ -19,11 +19,17 @@
  *
  */
 
-struct gps {
+struct osmo_gps {
 	/* GPS device */
 	uint8_t		enable;
+
+#ifdef _USE_GPSD
+	char		gpsd_host[32];
+	char		gpsd_port[6];
+#else
 	char		device[32];
 	uint32_t	baud;
+#endif
 
 	/* current data */
 	uint8_t		valid; /* we have a fix */
@@ -31,10 +37,10 @@ struct gps {
 	double		latitude, longitude;
 };
 
-extern struct gps gps;
+extern struct osmo_gps gps;
 
-int gps_open(void);
-void gps_close(void);
-void gps_init(void);
+int osmo_gps_open(void);
+void osmo_gps_close(void);
+void osmo_gps_init(void);
 
 
diff --git a/src/host/layer23/src/common/gps.c b/src/host/layer23/src/common/gps.c
index a092cd0..8b66363 100644
--- a/src/host/layer23/src/common/gps.c
+++ b/src/host/layer23/src/common/gps.c
@@ -27,26 +27,126 @@
 #include <errno.h>
 #include <time.h>
 
+#ifdef _USE_GPSD
+#include <gps.h>
+#endif
+
 #include <osmocore/utils.h>
 
 #include <osmocom/bb/common/osmocom_data.h>
 #include <osmocom/bb/common/logging.h>
 #include <osmocom/bb/common/gps.h>
 
-struct gps gps = {
+struct osmo_gps gps = {
 	0,
+#ifdef _USE_GPSD
+    "localhost",
+	"2947",
+#else
 	"/dev/ttyACM0",
 	0,
-
+#endif
 	0,
 	0,
-	0,0,
+	0,0
 };
 
 static struct bsc_fd gps_bfd;
+
+#ifdef _USE_GPSD
+
+static struct gps_data_t* gdata;
+
+int osmo_gps_cb(struct bsc_fd *bfd, unsigned int what)
+{
+	struct tm *tm;
+	unsigned diff = 0;
+	
+	gps.valid = 0;
+	
+	/* gps is offline */
+	if (gdata->online)
+	    goto gps_not_ready;
+	
+	/* gps has no data */
+	if (gps_waiting(gdata))
+	    goto gps_not_ready;
+	
+	/* polling returned an error */
+	if (gps_poll(gdata))
+	    goto gps_not_ready;
+	
+	/* data are valid */
+	if (gdata->set & LATLON_SET) {
+		gps.valid = 1;
+		gps.gmt = gdata->fix.time;
+		tm = localtime(&gps.gmt);
+		diff = time(NULL) - gps.gmt;
+		gps.latitude = gdata->fix.latitude;
+		gps.longitude = gdata->fix.longitude;
+
+		LOGP(DGPS, LOGL_INFO, " time=%02d:%02d:%02d %04d-%02d-%02d, "
+			"diff-to-host=%d, latitude=%do%.4f, longitude=%do%.4f\n",
+			tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_year + 1900,
+			tm->tm_mday, tm->tm_mon + 1, diff,
+			(int)gps.latitude,
+			(gps.latitude - ((int)gps.latitude)) * 60.0,
+			(int)gps.longitude,
+			(gps.longitude - ((int)gps.longitude)) * 60.0);
+	}
+
+	return 0;
+
+gps_not_ready:
+	LOGP(DGPS, LOGL_DEBUG, "gps is offline");
+	return -1;
+}
+
+int osmo_gps_open(void)
+{
+	LOGP(DGPS, LOGL_INFO, "Connecting to gpsd at '%s:%s'\n", gps.gpsd_host, gps.gpsd_port);
+	
+	gps_bfd.data = NULL;
+	gps_bfd.when = BSC_FD_READ;
+	gps_bfd.cb = osmo_gps_cb;
+	
+	gdata = gps_open(gps.gpsd_host, gps.gpsd_port);
+	if (gdata == NULL) {
+		LOGP(DGPS, LOGL_ERROR, "Can't connect to gpsd\n");
+		return -1;
+	}
+	gps_bfd.fd = gdata->gps_fd;
+	if (gps_bfd.fd < 0)
+		return gps_bfd.fd;
+	   
+	if (gps_stream(gdata, WATCH_ENABLE, NULL) == -1) {
+		LOGP(DGPS, LOGL_ERROR, "Error in gps_stream()\n");
+		return -1;
+	}
+
+	bsc_register_fd(&gps_bfd);
+
+	return 0;
+}
+
+void osmo_gps_close(void)
+{
+	if (gps_bfd.fd <= 0)
+		return;
+
+	LOGP(DGPS, LOGL_INFO, "Disconnecting from gpsd\n");
+
+	bsc_unregister_fd(&gps_bfd);
+
+	gps_close(gdata);
+	gps_bfd.fd = -1; /* -1 or 0 indicates: 'close' */
+}
+
+#else
+
 static struct termios gps_termios, gps_old_termios;
 
-static int gps_line(char *line)
+static int osmo_gps_line(char *line)
 {
 	time_t gps_now, host_now;
 	struct tm *tm;
@@ -141,7 +241,7 @@ static int nmea_checksum(char *line)
 	return (strtoul(line+1, NULL, 16) == checksum);
 }
 
-int gps_cb(struct bsc_fd *bfd, unsigned int what)
+int osmo_gps_cb(struct bsc_fd *bfd, unsigned int what)
 {
 	char buff[128];
 	static char line[128];
@@ -165,7 +265,7 @@ int gps_cb(struct bsc_fd *bfd, unsigned int what)
 			if (!nmea_checksum(line))
 				fprintf(stderr, "NMEA checksum error\n");
 			else
-				gps_line(line);
+				osmo_gps_line(line);
 			continue;
 		}
 		line[lpos++] = buff[i++];
@@ -176,7 +276,7 @@ int gps_cb(struct bsc_fd *bfd, unsigned int what)
 	return 0;
 }
 
-int gps_open(void)
+int osmo_gps_open(void)
 {
 	int baud = 0;
 
@@ -187,7 +287,7 @@ int gps_open(void)
 
 	gps_bfd.data = NULL;
 	gps_bfd.when = BSC_FD_READ;
-	gps_bfd.cb = gps_cb;
+	gps_bfd.cb = osmo_gps_cb;
 	gps_bfd.fd = open(gps.device, O_RDONLY);
 	if (gps_bfd.fd < 0)
 		return gps_bfd.fd;
@@ -227,7 +327,7 @@ int gps_open(void)
 	return 0;
 }
 
-void gps_close(void)
+void osmo_gps_close(void)
 {
 	if (gps_bfd.fd <= 0)
 		return;
@@ -242,8 +342,8 @@ void gps_close(void)
 	close(gps_bfd.fd);
 	gps_bfd.fd = -1; /* -1 or 0 indicates: 'close' */
 }
-
-void gps_init(void)
+#endif
+void osmo_gps_init(void)
 {
 	memset(&gps_bfd, 0, sizeof(gps_bfd));
 }
diff --git a/src/host/layer23/src/misc/app_cell_log.c b/src/host/layer23/src/misc/app_cell_log.c
index 0d61226..7a2c67a 100644
--- a/src/host/layer23/src/misc/app_cell_log.c
+++ b/src/host/layer23/src/misc/app_cell_log.c
@@ -92,8 +92,13 @@ static int l23_getopt_options(struct option **options)
 		{"logfile", 1, 0, 'l'},
 		{"rach", 1, 0, 'r'},
 		{"no-rach", 1, 0, 'n'},
+#ifdef _USE_GPSD
+		{"gpsd-host", 1, 0, 'g'},
+		{"gpsd-port", 1, 0, 'p'}
+#else
 		{"gps", 1, 0, 'g'},
 		{"baud", 1, 0, 'b'}
+#endif
 	};
 
 	*options = opts;
@@ -103,11 +108,16 @@ static int l23_getopt_options(struct option **options)
 static int l23_cfg_print_help()
 {
 	printf("\nApplication specific\n");
-	printf("  -l --logfile LOGFILE		Logfile for the cell log.\n");
+	printf("  -l --logfile LOGFILE	Logfile for the cell log.\n");
 	printf("  -r --rach    RACH		Nr. of RACH bursts to send.\n");
 	printf("  -n --no-rach			Send no rach bursts.\n");
+#ifdef _USE_GPSD
+	printf("  -g --gpsd-host HOST	127.0.0.1. gpsd host.\n");
+	printf("  -p --port PORT		2947. gpsd port\n");
+#else
 	printf("  -g --gps DEVICE		/dev/ttyACM0. GPS device.\n");
 	printf("  -b --baud BAUDRAT		The baud rate of the GPS device\n");
+#endif
 	return 0;
 }
 
@@ -123,6 +133,20 @@ static int l23_cfg_handle(int c, const char *optarg)
 	case 'n':
 		RACH_MAX = 0;
 		break;
+#ifdef _USE_GPSD
+	case 'g':
+		snprintf(gps.gpsd_host, ARRAY_SIZE(gps.gpsd_host), "%s", optarg);
+		/* force string terminator */
+		gps.gpsd_host[ARRAY_SIZE(gps.gpsd_host) - 1] = '\0';
+		LOGP(DGPS, LOGL_INFO, "Using gpsd host %s\n", gps.gpsd_host);
+		break;
+	case 'p':
+		snprintf(gps.gpsd_port, ARRAY_SIZE(gps.gpsd_port), "%s", optarg);
+		/* force string terminator */
+		gps.gpsd_port[ARRAY_SIZE(gps.gpsd_port) - 1] = '\0';
+		LOGP(DGPS, LOGL_INFO, "Using gpsd port %s\n", gps.gpsd_port);
+		break;
+#else
 	case 'g':
 		snprintf(gps.device, ARRAY_SIZE(gps.device), "%s", optarg);
 		/* force string terminator */
@@ -133,14 +157,18 @@ static int l23_cfg_handle(int c, const char *optarg)
 		gps.baud = atoi(optarg);
 		LOGP(DGPS, LOGL_INFO, "Setting GPS baudrate to %u\n", gps.baud);
 		break;
+#endif
 	}
-
 	return 0;
 }
 
 static struct l23_app_info info = {
 	.copyright	= "Copyright (C) 2010 Andreas Eversberg\n",
+#ifdef _USE_GPSD
+	.getopt_string	= "l:r:ng:p:",
+#else
 	.getopt_string	= "l:r:ng:b:",
+#endif
 	.cfg_supported	= l23_cfg_supported,
 	.cfg_getopt_opt = l23_getopt_options,
 	.cfg_handle_opt	= l23_cfg_handle,
diff --git a/src/host/layer23/src/misc/cell_log.c b/src/host/layer23/src/misc/cell_log.c
index 93616f2..a0f9769 100644
--- a/src/host/layer23/src/misc/cell_log.c
+++ b/src/host/layer23/src/misc/cell_log.c
@@ -787,8 +787,8 @@ int scan_init(struct osmocom_ms *_ms)
 	memset(&timer, 0, sizeof(timer));
 	osmol2_register_handler(ms, &rcv_rsl);
 	gps.enable = 1;
-	gps_init();
-	if (gps_open())
+	osmo_gps_init();
+	if (osmo_gps_open())
 		gps.enable = 0;
 
 	if (!strcmp(logname, "-"))
@@ -809,7 +809,7 @@ int scan_exit(void)
 {
 	LOGP(DSUM, LOGL_INFO, "Scanner exit\n");
 	if (gps.valid)
-		gps_close();
+		osmo_gps_close();
 	if (logfp)
 		fclose(logfp);
 	unregister_signal_handler(SS_L1CTL, &signal_cb, NULL);
diff --git a/src/host/layer23/src/mobile/app_mobile.c b/src/host/layer23/src/mobile/app_mobile.c
index 822ea64..1bedb55 100644
--- a/src/host/layer23/src/mobile/app_mobile.c
+++ b/src/host/layer23/src/mobile/app_mobile.c
@@ -333,7 +333,7 @@ int l23_app_exit(void)
 	unregister_signal_handler(SS_L1CTL, &mobile_signal_cb, NULL);
 	unregister_signal_handler(SS_GLOBAL, &global_signal_cb, NULL);
 
-	gps_close();
+	osmo_gps_close();
 
 	return 0;
 }
@@ -353,7 +353,7 @@ int l23_app_init(int (*mncc_recv)(struct osmocom_ms *ms, int, void *),
 
 	mncc_recv_app = mncc_recv;
 
-	gps_init();
+	osmo_gps_init();
 
 	vty_init(&vty_info);
 	ms_vty_init();
diff --git a/src/host/layer23/src/mobile/vty_interface.c b/src/host/layer23/src/mobile/vty_interface.c
index 4cc2209..e6e2846 100644
--- a/src/host/layer23/src/mobile/vty_interface.c
+++ b/src/host/layer23/src/mobile/vty_interface.c
@@ -835,7 +835,7 @@ DEFUN(network_search, network_search_cmd, "network search MS_NAME",
 DEFUN(cfg_gps_enable, cfg_gps_enable_cmd, "gps enable",
 	"GPS receiver")
 {
-	if (gps_open()) {
+	if (osmo_gps_open()) {
 		gps.enable = 1;
 		vty_out(vty, "Failed to open GPS device!%s", VTY_NEWLINE);
 		return CMD_WARNING;
@@ -849,12 +849,41 @@ DEFUN(cfg_no_gps_enable, cfg_no_gps_enable_cmd, "no gps enable",
 	NO_STR "Disable GPS receiver")
 {
 	if (gps.enable)
-		gps_close();
+		osmo_gps_close();
 	gps.enable = 0;
 
 	return CMD_SUCCESS;
 }
 
+#ifdef _USE_GPSD
+DEFUN(cfg_gps_host, cfg_gps_host_cmd, "gps host HOST:PORT",
+	"GPS receiver\nSelect gpsd host and port\n"
+	"IP and port (optional) of the host running gpsd")
+{
+	char* colon = strstr(argv[0], ":");
+	if (colon != NULL) {
+		memcpy(gps.gpsd_host, argv[0], colon - argv[0] - 1);
+		gps.gpsd_host[colon - argv[0]] = '\0';
+		memcpy(gps.gpsd_port, colon, strlen(colon));
+		gps.gpsd_port[strlen(colon)] = '\0';
+	} else {
+		snprintf(gps.gpsd_host, ARRAY_SIZE(gps.gpsd_host), "%s", argv[0]);
+		gps.gpsd_host[ARRAY_SIZE(gps.gpsd_host) - 1] = '\0';
+		snprintf(gps.gpsd_port, ARRAY_SIZE(gps.gpsd_port), "2947");
+		gps.gpsd_port[ARRAY_SIZE(gps.gpsd_port) - 1] = '\0';
+	}
+	if (gps.enable) {
+		osmo_gps_close();
+		if (osmo_gps_open()) {
+			vty_out(vty, "Failed to connect to gpsd host!%s",
+				VTY_NEWLINE);
+			return CMD_WARNING;
+		}
+	}
+
+	return CMD_SUCCESS;
+}
+#else
 DEFUN(cfg_gps_device, cfg_gps_device_cmd, "gps device DEVICE",
 	"GPS receiver\nSelect serial device\n"
 	"Full path of serial device including /dev/")
@@ -862,8 +891,8 @@ DEFUN(cfg_gps_device, cfg_gps_device_cmd, "gps device DEVICE",
 	strncpy(gps.device, argv[0], sizeof(gps.device));
 	gps.device[sizeof(gps.device) - 1] = '\0';
 	if (gps.enable) {
-		gps_close();
-		if (gps_open()) {
+		osmo_gps_close();
+		if (osmo_gps_open()) {
 			vty_out(vty, "Failed to open GPS device!%s",
 				VTY_NEWLINE);
 			return CMD_WARNING;
@@ -872,7 +901,9 @@ DEFUN(cfg_gps_device, cfg_gps_device_cmd, "gps device DEVICE",
 
 	return CMD_SUCCESS;
 }
+#endif
 
+#ifndef _USE_GPSD
 DEFUN(cfg_gps_baud, cfg_gps_baud_cmd, "gps baudrate "
 	"(default|4800|""9600|19200|38400|57600|115200)",
 	"GPS receiver\nSelect baud rate\nDefault, don't modify\n\n\n\n\n\n")
@@ -882,8 +913,8 @@ DEFUN(cfg_gps_baud, cfg_gps_baud_cmd, "gps baudrate "
 	else
 		gps.baud = atoi(argv[0]);
 	if (gps.enable) {
-		gps_close();
-		if (gps_open()) {
+		osmo_gps_close();
+		if (osmo_gps_open()) {
 			gps.enable = 0;
 			vty_out(vty, "Failed to open GPS device!%s",
 				VTY_NEWLINE);
@@ -893,6 +924,7 @@ DEFUN(cfg_gps_baud, cfg_gps_baud_cmd, "gps baudrate "
 
 	return CMD_SUCCESS;
 }
+#endif
 
 /* per MS config */
 DEFUN(cfg_ms, cfg_ms_cmd, "ms MS_NAME",
@@ -1172,11 +1204,16 @@ static int config_write(struct vty *vty)
 {
 	struct osmocom_ms *ms;
 
+#ifdef _USE_GPSD
+	vty_out(vty, "gpsd host %s%s", gps.gpsd_host, VTY_NEWLINE);
+	vty_out(vty, "gpsd port %s%s", gps.gpsd_port, VTY_NEWLINE);
+#else	
 	vty_out(vty, "gps device %s%s", gps.device, VTY_NEWLINE);
 	if (gps.baud)
 		vty_out(vty, "gps baudrate %d%s", gps.baud, VTY_NEWLINE);
 	else
 		vty_out(vty, "gps baudrate default%s", VTY_NEWLINE);
+#endif		
 	vty_out(vty, "%sgps enable%s", (gps.enable) ? "" : "no ", VTY_NEWLINE);
 	vty_out(vty, "!%s", VTY_NEWLINE);
 
@@ -2268,8 +2305,12 @@ int ms_vty_init(void)
 	install_element(ENABLE_NODE, &call_retr_cmd);
 	install_element(ENABLE_NODE, &call_dtmf_cmd);
 
+#ifdef _USE_GPSD
+	install_element(CONFIG_NODE, &cfg_gps_host_cmd);
+#else	
 	install_element(CONFIG_NODE, &cfg_gps_device_cmd);
 	install_element(CONFIG_NODE, &cfg_gps_baud_cmd);
+#endif
 	install_element(CONFIG_NODE, &cfg_gps_enable_cmd);
 	install_element(CONFIG_NODE, &cfg_no_gps_enable_cmd);
 
diff --git a/src/target/firmware/Makefile b/src/target/firmware/Makefile
index ad46fb5..dc4fc72 100644
--- a/src/target/firmware/Makefile
+++ b/src/target/firmware/Makefile
@@ -81,7 +81,7 @@ ANY_APP_LIBS+=calypso/libcalypso.a layer1/liblayer1.a lib/libmini.a comm/libcomm
 -include Makefile.inc
 
 # Uncomment this line if you want to enable Tx (Transmit) Support.
-#CFLAGS += -DCONFIG_TX_ENABLE
+CFLAGS += -DCONFIG_TX_ENABLE
 
 # Uncomment this line if you want to write to flash.
 #CFLAGS += -DCONFIG_FLASH_WRITE
