static int add_rule(const char *func, const char *file, int line, int off) { mrp_htbl_t *ht; char *rule, *r, buf[PATH_MAX * 2]; if (rules_on == NULL) if (!init_rules()) return FALSE; r = rule = NULL; if (!off) ht = rules_on; else ht = rules_off; if (func != NULL && file == NULL && line == 0) { r = mrp_htbl_lookup(ht, (void *)func); rule = (char *)func; } else if (func != NULL && file != NULL && line == 0) { snprintf(buf, sizeof(buf), "%s@%s", func, file); r = mrp_htbl_lookup(ht, (void *)buf); rule = buf; } else if (func == NULL && file != NULL && line == 0) { snprintf(buf, sizeof(buf), "@%s", file); r = mrp_htbl_lookup(ht, (void *)buf); rule = buf; } else if (func == NULL && file != NULL && line > 0) { snprintf(buf, sizeof(buf), "%s:%d", file, line); r = mrp_htbl_lookup(ht, (void *)buf); rule = buf; } if (r != NULL) return FALSE; rule = mrp_strdup(rule); if (rule == NULL) return FALSE; if (mrp_htbl_insert(ht, rule, rule)) { mrp_debug_stamp++; return TRUE; } else { mrp_free(rule); return FALSE; } }
void clients_player_disappeared(context_t *ctx, const char *name) { clients_t *clients; player_t *player, *removed; if (ctx && (clients = ctx->clients) && clients->player.name) { if ((player = mrp_htbl_lookup(clients->player.name, (void *)name))) { removed = mrp_htbl_remove(clients->player.addr, (void *)player->address, FALSE); if (player != removed) { mrp_log_error("mpris2 client: confused with data structures " "when removing '%s'", player->address); } else { mrp_free((void *)player->address); player->address = NULL; player->state = UNKNOWN; player->ready = false; playlist_free(player->nlist, player->lists); player->nlist = 0; player->lists = NULL; player->active_list = NULL; mrp_log_info("mrpis2 client '%s' disappeared", name); } } } }
mrp_res_resource_set_t *acquire_resource_set_response(mrp_msg_t *msg, mrp_res_context_t *cx, void **pcursor) { int status; uint32_t rset_id; mrp_res_resource_set_t *rset = NULL; if (!fetch_resource_set_id(msg, pcursor, &rset_id) || !fetch_status(msg, pcursor, &status)) { mrp_log_error("ignoring malformed response to resource set"); goto error; } if (status) { mrp_log_error("acquiring of resource set failed. error code %u",status); goto error; } /* we need the previous resource set because the new one doesn't * tell us the resource set class */ rset = mrp_htbl_lookup(cx->priv->rset_mapping, u_to_p(rset_id)); if (!rset) { mrp_log_error("no rset found!"); goto error; } return rset; error: return NULL; }
static int resource_set_get_resources(void *data, lua_State *L, int member, mrp_lua_value_t *v) { resource_set_lua_t *rset; void *iter = NULL; mrp_resource_t *resource; mrp_resource_mask_t grant, advice; MRP_UNUSED(member); MRP_UNUSED(v); mrp_debug("> resource_set_get_resources"); rset = (resource_set_lua_t *) data; if (!rset) return luaL_error(L, "internal error"); grant = mrp_get_resource_set_grant(rset->resource_set); advice = mrp_get_resource_set_advice(rset->resource_set); lua_newtable(L); /* push all resource objects to a table and return it */ while ((resource = mrp_resource_set_iterate_resources(rset->resource_set, &iter))) { const char *name = mrp_resource_get_name(resource); mrp_resource_mask_t mask = mrp_resource_get_mask(resource); /* fetch and update the resource object */ resource_lua_t *res = (resource_lua_t *) mrp_htbl_lookup(rset->resources, (void *) name); if (!res) { mrp_log_error("resources out of sync: %s not found", name); continue; } /* mrp_lua_object_ref_value(res, L, 0); */ res->acquired = !!(mask & grant); res->available = !!(mask & advice); /* TODO: update attributes */ /* push the resource to the table */ lua_pushstring(L, res->resource_name); mrp_lua_push_object(L, res); lua_settable(L, -3); } return 1; }
player_t *clients_find_player_by_name(context_t *ctx, const char *name) { clients_t *clients; player_t *player; if (!ctx || !(clients = ctx->clients)) return NULL; player = mrp_htbl_lookup(clients->player.name, (void *)name); return player; }
player_t *clients_find_player_by_address(context_t *ctx, const char *address) { clients_t *clients; player_t *player; if (!ctx || !(clients = ctx->clients)) return NULL; player = mrp_htbl_lookup(clients->player.addr, (void *)address); return player; }
void clients_player_appeared(context_t *ctx, const char *name, const char *address) { clients_t *clients; player_t *player; if (ctx && (clients = ctx->clients) && clients->player.name) { if ((player = mrp_htbl_lookup(clients->player.name, (void *)name))) { mrp_free((void *)player->address); player->address = mrp_strdup(address); mrp_htbl_insert(clients->player.addr, (void *)player->address, player); mrp_log_info("mrpis2 client '%s' appeared (address %s)", name, address); dbusif_query_player_properties(player); } } }
int mrp_debug_check(const char *func, const char *file, int line) { char buf[2 * PATH_MAX], *base; void *key; if (!debug_enabled || rules_on == NULL) return FALSE; base = NULL; key = (void *)func; if (mrp_htbl_lookup(rules_on, key) != NULL) goto check_suppress; base = strrchr(file, '/'); if (base != NULL) base++; key = buf; snprintf(buf, sizeof(buf), "@%s", file); if (mrp_htbl_lookup(rules_on, key) != NULL) goto check_suppress; if (base != NULL) { snprintf(buf, sizeof(buf), "@%s", base); if (mrp_htbl_lookup(rules_on, key) != NULL) goto check_suppress; } snprintf(buf, sizeof(buf), "%s@%s", func, file); if (mrp_htbl_lookup(rules_on, key) != NULL) goto check_suppress; snprintf(buf, sizeof(buf), "%s:%d", file, line); if (mrp_htbl_lookup(rules_on, key) != NULL) goto check_suppress; if (mrp_htbl_lookup(rules_on, (void *)WILDCARD) == NULL) return FALSE; check_suppress: if (rules_off == NULL) return TRUE; key = (void *)func; if (mrp_htbl_lookup(rules_off, key) != NULL) return FALSE; key = buf; snprintf(buf, sizeof(buf), "@%s", file); if (mrp_htbl_lookup(rules_off, key) != NULL) return FALSE; if (base != NULL) { snprintf(buf, sizeof(buf), "@%s", base); if (mrp_htbl_lookup(rules_off, key) != NULL) return FALSE; } snprintf(buf, sizeof(buf), "%s@%s", func, file); if (mrp_htbl_lookup(rules_off, key) != NULL) return FALSE; snprintf(buf, sizeof(buf), "%s:%d", file, line); if (mrp_htbl_lookup(rules_off, key) != NULL) return FALSE; return TRUE; }
static void resource_event(mrp_msg_t *msg, mrp_res_context_t *cx, int32_t seqno, void **pcursor) { uint32_t rset_id; uint32_t grant, advice; mrp_resproto_state_t state; uint16_t tag; uint16_t type; mrp_msg_value_t value; size_t size; uint32_t resid; const char *resnam; mrp_res_attribute_t attrs[ATTRIBUTE_MAX + 1]; int n_attrs; uint32_t mask, all = 0x0, mandatory = 0x0; uint32_t i; mrp_res_resource_set_t *rset; mrp_log_info("Resource event (request no %u):", seqno); if (!fetch_resource_set_id(msg, pcursor, &rset_id) || !fetch_resource_set_state(msg, pcursor, &state) || !fetch_resource_set_mask(msg, pcursor, 0, &grant) || !fetch_resource_set_mask(msg, pcursor, 1, &advice)) { mrp_log_error("failed to fetch data from message"); goto malformed; } /* Update our "master copy" of the resource set. */ rset = mrp_htbl_lookup(cx->priv->rset_mapping, u_to_p(rset_id)); if (!rset) { mrp_log_error("resource event outside the resource set lifecycle"); goto malformed; } #if 0 switch (state) { case RESPROTO_RELEASE: rset->state = MRP_RES_RESOURCE_LOST; break; case RESPROTO_ACQUIRE: rset->state = MRP_RES_RESOURCE_ACQUIRED; break; } #endif while (mrp_msg_iterate(msg, pcursor, &tag, &type, &value, &size)) { mrp_res_resource_t *res = NULL; if ((tag != RESPROTO_RESOURCE_ID || type != MRP_MSG_FIELD_UINT32) || !fetch_resource_name(msg, pcursor, &resnam)) { mrp_log_error("failed to read resource from message"); goto malformed; } res = get_resource_by_name(rset, resnam); if (!res) { mrp_log_error("resource doesn't exist in resource set"); goto malformed; } resid = value.u32; mrp_log_info("data for '%s': %d", res->name, resid); n_attrs = fetch_attribute_array(msg, pcursor, ATTRIBUTE_MAX + 1, attrs); if (n_attrs < 0) { mrp_log_error("failed to read attributes from message"); goto malformed; } /* TODO: attributes */ } /* go through all resources and see if they have been modified */ for (i = 0; i < rset->priv->num_resources; i++) { mrp_res_resource_t *res = rset->priv->resources[i]; mask = (1UL << res->priv->server_id); all |= mask; if (res->priv->mandatory) mandatory |= mask; if (grant & mask) { res->state = MRP_RES_RESOURCE_ACQUIRED; } #if 1 else { res->state = MRP_RES_RESOURCE_LOST; } #else else if (advice & mask) { res->state = MRP_RES_RESOURCE_AVAILABLE; } else { res->state = MRP_RES_RESOURCE_LOST; } #endif }