diff options
author | Janos Kovacs <janos.f.kovacs@nokia.com> | 2010-01-06 20:45:44 +0200 |
---|---|---|
committer | Janos Kovacs <janos.f.kovacs@nokia.com> | 2010-01-06 20:45:44 +0200 |
commit | c12c6cc33e520fe1e233dfe1cc0ec21913b58b06 (patch) | |
tree | db1e0282a13861bdbd801738fd529937a895c751 | |
parent | c3f11b3140cb185f1b004e4d442f64831a45ff83 (diff) |
support for 'mode' bits
-rw-r--r-- | client/client.c | 97 | ||||
-rw-r--r-- | src/dbus-msg.c | 8 | ||||
-rw-r--r-- | src/dbus-proto.c | 8 | ||||
-rw-r--r-- | src/internal-proto.c | 9 | ||||
-rw-r--r-- | src/res-msg.c | 62 | ||||
-rw-r--r-- | src/res-msg.h | 9 | ||||
-rw-r--r-- | src/res-set-private.h | 6 | ||||
-rw-r--r-- | src/res-set.c | 8 | ||||
-rw-r--r-- | src/res-set.h | 4 |
9 files changed, 180 insertions, 31 deletions
diff --git a/client/client.c b/client/client.c index 0730c32..9bd0d30 100644 --- a/client/client.c +++ b/client/client.c @@ -11,6 +11,7 @@ #include <glib.h> #include <dbus/dbus.h> +#include <dbus/dbus-glib-lowlevel.h> #include <res-conn.h> @@ -24,6 +25,7 @@ typedef struct { int trace; uint32_t id; char *class; + uint32_t mode; resmsg_rset_t rset; int verbose; } conf_t; @@ -34,6 +36,11 @@ typedef struct { } rdef_t; typedef struct { + uint32_t value; + const char *name; +} mdef_t; + +typedef struct { GIOChannel *chan; guint evsrc; int accept; @@ -72,6 +79,7 @@ static void usage(int); static void parse_options(int, char **); static char *parse_class_string(char *); static uint32_t parse_resource_list(char *, int); +static uint32_t parse_mode_values(char *, int); static char *exe_name = ""; @@ -232,7 +240,7 @@ static void parse_input(void) char *str = input.buf; char *p; char *rs; - uint32_t res[3]; + uint32_t res[4]; int i; resmsg_t msg; @@ -257,7 +265,7 @@ static void parse_input(void) else if (!strncmp(str, "update", 6)) { rs = str = skip_whitespaces(str + 6); - for (i = 0; i < 3; i++) { + for (i = 0; i < 4; i++) { if ((p = strchr(str, ':')) != NULL) *p = '\0'; @@ -281,8 +289,9 @@ static void parse_input(void) memset(&msg, 0, sizeof(resmsg_t)); msg.record.type = RESMSG_UPDATE; msg.record.rset.all = res[0]; - msg.record.rset.share = res[1]; - msg.record.rset.opt = res[2]; + msg.record.rset.opt = res[1]; + msg.record.rset.share = res[2]; + msg.record.rset.mask = res[3]; msg.record.class = config.class; manager_send_message(&msg); } @@ -413,9 +422,11 @@ static void connect_to_manager(resconn_t *rc) resmsg.record.id = config.id; resmsg.record.reqno = ++reqno; resmsg.record.rset.all = config.rset.all; - resmsg.record.rset.share = config.rset.share; resmsg.record.rset.opt = config.rset.opt; + resmsg.record.rset.share = config.rset.share; + resmsg.record.rset.mask = config.rset.mask; resmsg.record.class = config.class; + resmsg.record.mode = config.mode; rset = resconn_connect(rc, &resmsg, manager_status); @@ -564,18 +575,22 @@ static void print_message(char *fmt, ...) static void usage(int exit_code) { - printf("usage: %s [-h] [-t] [-v]" - "[-o optional-resources] [-s shared-resources] " + printf("usage: %s [-h] [-t] [-v] [-f mode-values]" + "[-o optional-resources] [-s shared-resources -m shared-mask] " "class all-resources\n", exe_name); printf("\toptions:\n"); printf("\t h\tprint this help message and exit\n"); printf("\t t\ttrace messages\n"); printf("\t v\tverbose printouts\n"); + printf("\t f\tmode values. See 'modes' below for the " + "\n\t\tsyntax of <mode-values>\n"); printf("\t o\toptional resources. See 'resources' below for the " - "syntax of\n\t\t<optional resources>\n"); + "syntax of\n\t\t<optional-resources>\n"); printf("\t s\tshared resources. See 'resources' below for the " - "syntax of\n\t\t<shared resources>\n"); + "syntax of\n\t\t<shared-resources>\n"); + printf("\t m\tshared resource mask. See 'resources' below for the " + "syntax of\n\t\t<shared-mask>\n"); printf("\tclass:\n"); printf("\t\tcall\t- for native or 3rd party telephony\n"); printf("\t\tringtone - for ringtones\n"); @@ -589,6 +604,9 @@ static void usage(int exit_code) printf("\t\tAudioRecording\n"); printf("\t\tVideoRecording\n"); printf("\t no whitespace allowed in the resource list.\n"); + printf("\tmodes:\n"); + printf("\t comma separated lis of the following modes\n"); + printf("\t\tAutoRelease\n"); exit(exit_code); } @@ -602,15 +620,17 @@ static void parse_options(int argc, char **argv) config.trace = FALSE; config.id = 1; - while ((option = getopt(argc, argv, "htvo:s:")) != -1) { + while ((option = getopt(argc, argv, "htvf:s:o:m:")) != -1) { switch (option) { case 'h': usage(0); break; case 't': config.trace = TRUE; break; case 'v': config.verbose = TRUE; break; + case 'f': config.mode = parse_mode_values(optarg, 1); break; case 'o': config.rset.opt = parse_resource_list(optarg, 1); break; case 's': config.rset.share = parse_resource_list(optarg, 1); break; + case 'm': config.rset.mask = parse_resource_list(optarg, 1); break; default: usage(EINVAL); break; } @@ -627,8 +647,12 @@ static void parse_options(int argc, char **argv) print_error("optonal resources are not subset of all resources"); } - if ((config.rset.all | config.rset.share) != config.rset.all) { - print_error("shared resources are not subset of all resources "); + if ((config.rset.all | config.rset.mask) != config.rset.all) { + print_error("shared resource mask is not subset of all resources "); + } + + if ((config.rset.mask | config.rset.share) != config.rset.mask) { + print_error("shared resource values are not subset of shared mask "); } } @@ -650,7 +674,7 @@ static char *parse_class_string(char *str) return str; } -uint32_t parse_resource_list(char *rlist_str, int exit_if_error) +static uint32_t parse_resource_list(char *rlist_str, int exit_if_error) { static rdef_t rdef[] = { { RESMSG_AUDIO_PLAYBACK , "AudioPlayback" }, @@ -700,6 +724,53 @@ uint32_t parse_resource_list(char *rlist_str, int exit_if_error) return rlist; } +static uint32_t parse_mode_values(char *mval_str, int exit_if_error) +{ + static rdef_t mdef[] = { + { RESMSG_MODE_AUTO_RELEASE , "AutoRelease" }, + { 0 , NULL } + }; + + uint32_t mode = 0; + char buf[256]; + rdef_t *md; + char *p; + char *e; + + if (mval_str == NULL) + print_message("missing mode values"); + else { + strncpy(buf, mval_str, sizeof(buf)); + buf[sizeof(buf)-1] = '\0'; + + p = buf; + + do { + if ((e = strchr(p, ',')) != NULL) + *e++ = '\0'; + + for (md = mdef; md->name != NULL; md++) { + if (!strcmp(p, md->name)) + break; + } + + if (!md->value) { + print_message("invalid resource values '%s'", mval_str); + mode = 0; + break; + } + + mode |= md->value; + + } while((p = e) != NULL); + } + + if (!mode && exit_if_error) + exit(EINVAL); + + return mode; +} + /* * Local Variables: * c-basic-offset: 4 diff --git a/src/dbus-msg.c b/src/dbus-msg.c index 9c66012..273db63 100644 --- a/src/dbus-msg.c +++ b/src/dbus-msg.c @@ -40,10 +40,12 @@ DBusMessage *resmsg_dbus_compose_message(const char *dest, DBUS_TYPE_UINT32, &record->id, DBUS_TYPE_UINT32, &record->reqno, DBUS_TYPE_UINT32, &record->rset.all, - DBUS_TYPE_UINT32, &record->rset.share, DBUS_TYPE_UINT32, &record->rset.opt, + DBUS_TYPE_UINT32, &record->rset.share, + DBUS_TYPE_UINT32, &record->rset.mask, DBUS_TYPE_STRING, record->class ? &record->class : &empty_str, + DBUS_TYPE_UINT32, &record->mode, DBUS_TYPE_INVALID); break; @@ -171,9 +173,11 @@ resmsg_t *resmsg_dbus_parse_message(DBusMessage *dbusmsg, resmsg_t *resmsg) DBUS_TYPE_UINT32, &record->id, DBUS_TYPE_UINT32, &record->reqno, DBUS_TYPE_UINT32, &record->rset.all, - DBUS_TYPE_UINT32, &record->rset.share, DBUS_TYPE_UINT32, &record->rset.opt, + DBUS_TYPE_UINT32, &record->rset.share, + DBUS_TYPE_UINT32, &record->rset.mask, DBUS_TYPE_STRING, &record->class, + DBUS_TYPE_UINT32, &record->mode, DBUS_TYPE_INVALID); break; diff --git a/src/dbus-proto.c b/src/dbus-proto.c index 657d0a2..f3dd6f7 100644 --- a/src/dbus-proto.c +++ b/src/dbus-proto.c @@ -104,12 +104,14 @@ static resset_t *connect_to_manager(resconn_t *rcon, resmsg_t *resmsg) uint32_t id = resmsg->record.id; resmsg_rset_t *flags = &resmsg->record.rset; const char *class = resmsg->record.class; + uint32_t mode = resmsg->record.mode; resset_t *rset; if ((rset = resset_find(rcon, name, id)) == NULL) { if (register_client_object(&rcon->dbus, id)) { rset = resset_create(rcon, name, id, RESPROTO_RSET_STATE_CREATED, - class, flags->all, flags->share, flags->opt); + class, mode, flags->all, flags->opt, + flags->share, flags->mask); } } @@ -601,9 +603,11 @@ static DBusHandlerResult manager_method(DBusConnection *dcon, rset = resset_create(rcon, sender, resmsg.any.id, RESPROTO_RSET_STATE_CONNECTED, resmsg.record.class, + resmsg.record.mode, resmsg.record.rset.all, + resmsg.record.rset.opt, resmsg.record.rset.share, - resmsg.record.rset.opt); + resmsg.record.rset.mask); if (rset != NULL && watch_client(&rcon->dbus, sender, TRUE)) { dbus_message_ref(dbusmsg); diff --git a/src/internal-proto.c b/src/internal-proto.c index 5a55376..842a46b 100644 --- a/src/internal-proto.c +++ b/src/internal-proto.c @@ -91,11 +91,13 @@ static resset_t *connect_to_manager(resconn_t *rcon, resmsg_t *resmsg) uint32_t id = resmsg->any.id; resmsg_rset_t *flags = &resmsg->record.rset; const char *class = resmsg->record.class; + uint32_t mode = resmsg->record.mode; resset_t *rset; if ((rset = resset_find(rcon, name, id)) == NULL) rset = resset_create(rcon, name, id, RESPROTO_RSET_STATE_CREATED, - class, flags->all, flags->share, flags->opt); + class, mode, flags->all, flags->opt, + flags->share, flags->mask); return rset; } @@ -285,6 +287,7 @@ static void receive_message_init(resconn_internal_t *rcon, resconn_qitem_t *item; resmsg_rset_t *flags; const char *class; + uint32_t mode; @@ -293,12 +296,14 @@ static void receive_message_init(resconn_internal_t *rcon, if (msg->type == RESMSG_REGISTER) { class = msg->record.class; + mode = msg->record.mode; flags = &msg->record.rset; if ((resset_find((resconn_t *)rcon, peer, msg->any.id)) == NULL) { resset_create((resconn_t *)rcon, peer, msg->any.id, RESPROTO_RSET_STATE_CONNECTED, - class, flags->all, flags->share, flags->opt); + class, mode, flags->all, flags->opt, + flags->share, flags->mask); } } diff --git a/src/res-msg.c b/src/res-msg.c index 105f8ae..d4280d2 100644 --- a/src/res-msg.c +++ b/src/res-msg.c @@ -8,6 +8,7 @@ #include "visibility.h" static char *flag_str(uint32_t); +static char *mode_str(uint32_t); EXPORT char *resmsg_dump_message(resmsg_t *resmsg, @@ -27,6 +28,7 @@ EXPORT char *resmsg_dump_message(resmsg_t *resmsg, int l; char *p; char r[512]; + char m[512]; resmsg_rset_t *rset; resmsg_record_t *record; resmsg_possess_t *possess; @@ -51,11 +53,13 @@ EXPORT char *resmsg_dump_message(resmsg_t *resmsg, case RESMSG_UPDATE: record = &resmsg->record; rset = &record->rset; - PRINT("rset.all : %s" , resmsg_res_str(rset->all , r, sizeof(r))); - PRINT("rset.share: %s" , resmsg_res_str(rset->share, r, sizeof(r))); - PRINT("rset.opt : %s" , resmsg_res_str(rset->opt , r, sizeof(r))); + PRINT("rset.all : %s" , resmsg_res_str(rset->all , r, sizeof(r))); + PRINT("rset.opt : %s" , resmsg_res_str(rset->opt , r, sizeof(r))); + PRINT("rset.share: %s" , resmsg_res_str(rset->share, r, sizeof(r))); + PRINT("rset.mask : %s" , resmsg_res_str(rset->mask , r, sizeof(r))); PRINT("class : '%s'", record->class && record->class[0] ? record->class : "<unknown>"); + PRINT("mode : %s" , resmsg_mod_str(record->mode, m, sizeof(m))); break; case RESMSG_UNREGISTER: @@ -109,13 +113,52 @@ EXPORT char *resmsg_type_str(resmsg_type_t type) } +EXPORT char *resmsg_mod_str(uint32_t mod, char *buf, int len) +{ + char *p; + char *s; + char *mstr; + int l = len; + uint32_t m; + uint32_t i; + char hex[64]; + + if (!buf || len < 1) + return ""; + + *buf = '\0'; + + snprintf(hex, sizeof(hex), "0x%x", mod); + + for (p = buf, s = "", i = 0; i < 32 && mod != 0 && len > 0; i++) { + m = 1 << i; + + if ((mod & m) != 0) { + mod &= ~m; + + if ((mstr = mode_str(m)) != NULL) { + l = snprintf(p, len, "%s%s", s, mstr); + s = ","; + + p += l; + len -= l; + } + } + } /* for */ + + if (l > 0) + snprintf(p, len, "%s(%s)", *s ? " ":"<no-mode> ", hex); + + return buf; +} + EXPORT char *resmsg_res_str(uint32_t res, char *buf, int len) { char *p; char *s; char *f; - int l; + int l = len; uint32_t m; uint32_t i; char hex[64]; @@ -165,6 +208,17 @@ static char *flag_str(uint32_t flag) } +static char *mode_str(uint32_t mode_bit) +{ + char *str; + + switch (mode_bit) { + case RESMSG_MODE_AUTO_RELEASE: str = "AutoRelease"; break; + default: str = NULL; break; + } + + return str; +} /* diff --git a/src/res-msg.h b/src/res-msg.h index 3ae130f..e03b50e 100644 --- a/src/res-msg.h +++ b/src/res-msg.h @@ -15,6 +15,8 @@ extern "C" { #define RESMSG_AUDIO_RECORDING RESMSG_BIT(2) #define RESMSG_VIDEO_RECORDING RESMSG_BIT(3) +#define RESMSG_MODE_AUTO_RELEASE RESMSG_BIT(0) + typedef enum { RESMSG_INVALID = -1, @@ -35,14 +37,15 @@ typedef enum { typedef struct { uint32_t all; /* all the resources */ - uint32_t share; /* shareable resources (subset of all) */ uint32_t opt; /* optional resources (subset of all) */ + uint32_t share; /* shareable resource value */ + uint32_t mask; /* shereable resource mask (subset of all) */ } resmsg_rset_t; #define RESMSG_COMMON \ resmsg_type_t type; /* RESMSG_xxxx */ \ uint32_t id; /* resourse set ID */ \ - uint32_t reqno /* request number, if any */ \ + uint32_t reqno /* request number, if any */ typedef struct { RESMSG_COMMON; @@ -52,6 +55,7 @@ typedef struct { RESMSG_COMMON; /* RESMSG_[REGISTER|UPDATE] */ resmsg_rset_t rset; /* resource set */ char *class; /* optional application class */ + uint32_t mode; /* or'ed RESMSG_MODE_xxxx values */ } resmsg_record_t; typedef struct { @@ -83,6 +87,7 @@ typedef union resmsg_u { char *resmsg_dump_message(resmsg_t *, int, char *, int); char *resmsg_type_str(resmsg_type_t); char *resmsg_res_str(uint32_t, char *, int); +char *resmsg_mod_str(uint32_t, char *, int); #ifdef __cplusplus diff --git a/src/res-set-private.h b/src/res-set-private.h index 40f6d32..b5a9230 100644 --- a/src/res-set-private.h +++ b/src/res-set-private.h @@ -3,9 +3,9 @@ #include <res-set.h> -resset_t *resset_create(union resconn_u*, const char*, - uint32_t, resset_state_t, const char *, - uint32_t, uint32_t, uint32_t); +resset_t *resset_create(union resconn_u*, const char*, uint32_t, + resset_state_t, const char *, uint32_t, + uint32_t, uint32_t, uint32_t, uint32_t); void resset_destroy(resset_t *); void resset_ref(resset_t *); void resset_unref(resset_t *); diff --git a/src/res-set.c b/src/res-set.c index 6970de5..b400a09 100644 --- a/src/res-set.c +++ b/src/res-set.c @@ -11,9 +11,11 @@ resset_t *resset_create(resconn_t *rcon, uint32_t id, resset_state_t state, const char *class, + uint32_t mode, uint32_t all, + uint32_t opt, uint32_t share, - uint32_t opt) + uint32_t mask) { resset_t *rset; @@ -27,9 +29,11 @@ resset_t *resset_create(resconn_t *rcon, rset->id = id; rset->state = state; rset->class = strdup(class); + rset->mode = mode, rset->flags.all = all; - rset->flags.share = share; rset->flags.opt = opt; + rset->flags.share = share; + rset->flags.mask = mask; rcon->any.rsets = rset; } diff --git a/src/res-set.h b/src/res-set.h index 2e23255..72ba600 100644 --- a/src/res-set.h +++ b/src/res-set.h @@ -25,10 +25,12 @@ typedef struct resset_s { uint32_t id; resset_state_t state; char *class; + uint32_t mode; struct { uint32_t all; - uint32_t share; uint32_t opt; + uint32_t share; + uint32_t mask; } flags; void *userdata; } resset_t; |