From a72236a1d0effb1fe985f5685d40e6dc33ab65a3 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Fri, 27 Sep 2013 22:42:41 +0200 Subject: permit gsmd and libgsm to handle multiple instances By using differntly-named unix domain sockets, we can run multiple gsmd instances in parallel. --- include/gsmd/gsmd.h | 1 + include/libgsmd/libgsmd.h | 1 + src/gsmd/gsmd.c | 7 ++++++- src/gsmd/usock.c | 9 ++++++++- src/libgsmd/libgsmd.c | 19 ++++++++++++++++--- src/util/libgsmd-tool.c | 11 ++++++++--- 6 files changed, 40 insertions(+), 8 deletions(-) diff --git a/include/gsmd/gsmd.h b/include/gsmd/gsmd.h index 585d78d..47bc43d 100644 --- a/include/gsmd/gsmd.h +++ b/include/gsmd/gsmd.h @@ -74,6 +74,7 @@ struct gsmd; #define GSMD_ATCMD_TIMEOUT 60 /* If doesn get respond within 60 secs, discard */ struct gsmd { + unsigned int instance; unsigned int flags; int interpreter_ready; struct gsmd_fd gfd_uart; diff --git a/include/libgsmd/libgsmd.h b/include/libgsmd/libgsmd.h index a6a4252..3fce0f0 100644 --- a/include/libgsmd/libgsmd.h +++ b/include/libgsmd/libgsmd.h @@ -49,6 +49,7 @@ typedef int lgsm_msg_handler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh); /* initialize usage of libgsmd, obtain handle for othe API calls */ extern struct lgsm_handle *lgsm_init(const char *device); +extern struct lgsm_handle *lgsm_init_inst(unsigned int instance); /* Terminate usage of libgsmd */ extern int lgsm_exit(struct lgsm_handle *lh); diff --git a/src/gsmd/gsmd.c b/src/gsmd/gsmd.c index 9389f5f..20daa7f 100644 --- a/src/gsmd/gsmd.c +++ b/src/gsmd/gsmd.c @@ -317,6 +317,7 @@ static struct option opts[] = { { "version", 0, NULL, 'V' }, { "daemon", 0, NULL, 'd' }, { "help", 0, NULL, 'h' }, + { "instance", 1, NULL, 'i' }, { "device", 1, NULL, 'p' }, { "speed", 1, NULL, 's' }, { "logfile", 1, NULL, 'l' }, @@ -347,6 +348,7 @@ static void print_usage(void) "\t-V\t--version\tDisplay program version\n" "\t-d\t--daemon\tDeamonize\n" "\t-h\t--help\t\tDisplay this help message\n" + "\t-i\t--instance <0-255>\t\tInstance number to use\n" "\t-p dev\t--device dev\tSpecify serial device to be used\n" "\t-s spd\t--speed spd\tSpecify speed in bps (9600,38400,115200,...)\n" "\t-F\t--hwflow\tHardware Flow Control (RTS/CTS)\n" @@ -396,7 +398,7 @@ int main(int argc, char **argv) print_header(); /*FIXME: parse commandline, set daemonize, device, ... */ - while ((argch = getopt_long(argc, argv, "FVLdhp:s:l:e:v:m:w:", opts, NULL)) != -1) { + while ((argch = getopt_long(argc, argv, "FVLdhi:p:s:l:e:v:m:w:", opts, NULL)) != -1) { switch (argch) { case 'V': print_version(); @@ -416,6 +418,9 @@ int main(int argc, char **argv) print_usage(); exit(0); break; + case 'i': + g.instance = atoi(optarg); + break; case 'p': device = optarg; break; diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c index f258fd6..41814c8 100644 --- a/src/gsmd/usock.c +++ b/src/gsmd/usock.c @@ -1734,7 +1734,14 @@ int usock_init(struct gsmd *g) memset(&sun, 0, sizeof(sun)); sun.sun_family = AF_UNIX; - memcpy(sun.sun_path, GSMD_UNIX_SOCKET, sizeof(GSMD_UNIX_SOCKET)); + if (g->instance == 0) { + memcpy(sun.sun_path, GSMD_UNIX_SOCKET, + sizeof(GSMD_UNIX_SOCKET)); + } else { + sun.sun_path[0] = '\0'; + snprintf(sun.sun_path+1, sizeof(sun.sun_path)-1, "gsmd.%u", + g->instance); + } rc = bind(fd, (struct sockaddr *)&sun, sizeof(sun)); if (rc < 0) { diff --git a/src/libgsmd/libgsmd.c b/src/libgsmd/libgsmd.c index 1626b04..03642ea 100644 --- a/src/libgsmd/libgsmd.c +++ b/src/libgsmd/libgsmd.c @@ -64,7 +64,7 @@ static int lgsm_open_backend(struct lgsm_handle *lh, const char *device) { int rc; - if (!strcmp(device, LGSMD_DEVICE_GSMD)) { + if (!strncmp(device, LGSMD_DEVICE_GSMD, strlen(LGSMD_DEVICE_GSMD))) { struct sockaddr_un sun; /* use unix domain socket to gsm daemon */ @@ -74,7 +74,8 @@ static int lgsm_open_backend(struct lgsm_handle *lh, const char *device) memset(&sun, 0, sizeof(sun)); sun.sun_family = AF_UNIX; - memcpy(sun.sun_path, GSMD_UNIX_SOCKET, sizeof(GSMD_UNIX_SOCKET)); + sun.sun_path[0] = '\0'; + strncpy(sun.sun_path+1, device, sizeof(sun.sun_path)-1); rc = connect(lh->fd, (struct sockaddr *)&sun, sizeof(sun)); if (rc < 0) { @@ -184,6 +185,19 @@ struct lgsm_handle *lgsm_init(const char *device) return lh; } +struct lgsm_handle *lgsm_init_inst(unsigned int instance) +{ + struct lgsm_handle *lh = malloc(sizeof(*lh)); + char buf[32]; + if (instance == 0) + snprintf(buf, sizeof(buf), "gsmd"); + else + snprintf(buf, sizeof(buf), "gsmd.%u", instance); + + return lgsm_init(buf); +} + + int lgsm_exit(struct lgsm_handle *lh) { free(lh); @@ -191,7 +205,6 @@ int lgsm_exit(struct lgsm_handle *lh) return 0; } - static u_int16_t next_msg_id; int lgsm_send(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh) diff --git a/src/util/libgsmd-tool.c b/src/util/libgsmd-tool.c index 5fb1eca..4ef3df5 100644 --- a/src/util/libgsmd-tool.c +++ b/src/util/libgsmd-tool.c @@ -73,6 +73,7 @@ static int parse_mode(char *modestr) static struct option opts[] = { { "help", 0, 0, 'h' }, + { "instance", 1, 0, 'i' }, { "version", 0, 0, 'V' }, { "verbose", 0, 0, 'v' }, { "mode", 1, 0, 'm' }, @@ -85,6 +86,7 @@ static void help(void) { printf("Usage:\n" "\t-h\t--help\tPrint this Help message\n" + "\t-i\t--instance <0-255>\tWhich instance nubmer to use\n" "\t-V\t--version\tPrint version number\n" "\t-v\t--verbose\tBe more verbose\n" "\t-m\t--mode\tSet mode {shell,eventlog,atcmd}\n" @@ -100,7 +102,7 @@ static void dump_version(void) int main(int argc, char **argv) { char *pin = NULL; - int mode = MODE_NONE, shellwait = 0; + int mode = MODE_NONE, shellwait = 0, instance = 0; printf("libgsm-tool - (C) 2006-2007 by Harald Welte and OpenMoko, Inc.\n" " (C) 2012-2013 by Harald Welte\n" @@ -108,7 +110,7 @@ int main(int argc, char **argv) while (1) { int c, option_index = 0; - c = getopt_long(argc, argv, "vVhwm:p:", opts, &option_index); + c = getopt_long(argc, argv, "vVhi:wm:p:", opts, &option_index); if (c == -1) break; @@ -124,6 +126,9 @@ int main(int argc, char **argv) help(); exit(0); break; + case 'i': + instance = atoi(optarg); + break; case 'm': mode = parse_mode(optarg); if (mode < 0) { @@ -140,7 +145,7 @@ int main(int argc, char **argv) } } - lgsmh = lgsm_init(LGSMD_DEVICE_GSMD); + lgsmh = lgsm_init_inst(instance); if (!lgsmh) { fprintf(stderr, "Can't connect to gsmd\n"); exit(1); -- cgit v1.2.3