Work on introspection

This commit is contained in:
Wim Taymans 2016-12-02 13:38:43 +01:00
parent 7c29209023
commit b969623ec8
39 changed files with 1726 additions and 574 deletions

View file

@ -126,6 +126,99 @@ connection_parse_create_client_node (PinosConnection *conn, PinosMessageCreateCl
m->props = pinos_serialize_dict_deserialize (p, SPA_PTR_TO_INT (m->props)); m->props = pinos_serialize_dict_deserialize (p, SPA_PTR_TO_INT (m->props));
} }
static void
connection_parse_core_info (PinosConnection *conn, PinosMessageCoreInfo *m)
{
void *p;
PinosCoreInfo *di;
p = conn->in.data;
memcpy (m, p, sizeof (PinosMessageCoreInfo));
if (m->info) {
m->info = SPA_MEMBER (p, SPA_PTR_TO_INT (m->info), PinosCoreInfo);
di = m->info;
if (m->info->user_name)
m->info->user_name = SPA_MEMBER (di, SPA_PTR_TO_INT (m->info->user_name), const char);
if (m->info->host_name)
m->info->host_name = SPA_MEMBER (di, SPA_PTR_TO_INT (m->info->host_name), const char);
if (m->info->version)
m->info->version = SPA_MEMBER (di, SPA_PTR_TO_INT (m->info->version), const char);
if (m->info->name)
m->info->name = SPA_MEMBER (di, SPA_PTR_TO_INT (m->info->name), const char);
if (m->info->props)
m->info->props = pinos_serialize_dict_deserialize (di, SPA_PTR_TO_INT (m->info->props));
}
}
static void
connection_parse_module_info (PinosConnection *conn, PinosMessageModuleInfo *m)
{
void *p;
PinosModuleInfo *di;
p = conn->in.data;
memcpy (m, p, sizeof (PinosMessageModuleInfo));
if (m->info) {
m->info = SPA_MEMBER (p, SPA_PTR_TO_INT (m->info), PinosModuleInfo);
di = m->info;
if (m->info->name)
m->info->name = SPA_MEMBER (di, SPA_PTR_TO_INT (m->info->name), const char);
if (m->info->filename)
m->info->filename = SPA_MEMBER (di, SPA_PTR_TO_INT (m->info->filename), const char);
if (m->info->args)
m->info->args = SPA_MEMBER (di, SPA_PTR_TO_INT (m->info->args), const char);
if (m->info->props)
m->info->props = pinos_serialize_dict_deserialize (di, SPA_PTR_TO_INT (m->info->props));
}
}
static void
connection_parse_node_info (PinosConnection *conn, PinosMessageNodeInfo *m)
{
void *p;
PinosNodeInfo *di;
p = conn->in.data;
memcpy (m, p, sizeof (PinosMessageNodeInfo));
if (m->info) {
m->info = SPA_MEMBER (p, SPA_PTR_TO_INT (m->info), PinosNodeInfo);
di = m->info;
if (m->info->name)
m->info->name = SPA_MEMBER (di, SPA_PTR_TO_INT (m->info->name), const char);
if (m->info->props)
m->info->props = pinos_serialize_dict_deserialize (di, SPA_PTR_TO_INT (m->info->props));
}
}
static void
connection_parse_client_info (PinosConnection *conn, PinosMessageClientInfo *m)
{
void *p;
PinosClientInfo *di;
p = conn->in.data;
memcpy (m, p, sizeof (PinosMessageClientInfo));
if (m->info) {
m->info = SPA_MEMBER (p, SPA_PTR_TO_INT (m->info), PinosClientInfo);
di = m->info;
if (m->info->props)
m->info->props = pinos_serialize_dict_deserialize (di, SPA_PTR_TO_INT (m->info->props));
}
}
static void
connection_parse_link_info (PinosConnection *conn, PinosMessageLinkInfo *m)
{
void *p;
p = conn->in.data;
memcpy (m, p, sizeof (PinosMessageLinkInfo));
if (m->info)
m->info = SPA_MEMBER (p, SPA_PTR_TO_INT (m->info), PinosLinkInfo);
}
static void static void
connection_parse_node_update (PinosConnection *conn, PinosMessageNodeUpdate *nu) connection_parse_node_update (PinosConnection *conn, PinosMessageNodeUpdate *nu)
{ {
@ -297,8 +390,6 @@ connection_add_create_node (PinosConnection *conn, uint32_t dest_id, PinosMessag
if (m->props) { if (m->props) {
len = pinos_serialize_dict_serialize (p, m->props); len = pinos_serialize_dict_serialize (p, m->props);
d->props = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d)); d->props = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
} else {
d->props = 0;
} }
} }
@ -328,8 +419,223 @@ connection_add_create_client_node (PinosConnection *conn, uint32_t dest_id, Pino
if (m->props) { if (m->props) {
len = pinos_serialize_dict_serialize (p, m->props); len = pinos_serialize_dict_serialize (p, m->props);
d->props = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d)); d->props = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
} else { }
d->props = 0; }
static void
connection_add_core_info (PinosConnection *conn, uint32_t dest_id, PinosMessageCoreInfo *m)
{
size_t len, slen;
void *p;
PinosMessageCoreInfo *d;
/* calc len */
len = sizeof (PinosMessageCoreInfo);
if (m->info) {
len += sizeof (PinosCoreInfo);
len += m->info->user_name ? strlen (m->info->user_name) + 1 : 0;
len += m->info->host_name ? strlen (m->info->host_name) + 1 : 0;
len += m->info->version ? strlen (m->info->version) + 1 : 0;
len += m->info->name ? strlen (m->info->name) + 1 : 0;
len += pinos_serialize_dict_get_size (m->info->props);
}
p = connection_add_message (conn, dest_id, PINOS_MESSAGE_CORE_INFO, len);
memcpy (p, m, sizeof (PinosMessageCoreInfo));
d = p;
p = SPA_MEMBER (d, sizeof (PinosMessageCoreInfo), void);
if (m->info) {
PinosCoreInfo *di;
memcpy (p, m->info, sizeof (PinosCoreInfo));
di = p;
d->info = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
p = SPA_MEMBER (p, sizeof (PinosCoreInfo), void);
if (m->info->user_name) {
slen = strlen (m->info->user_name) + 1;
memcpy (p, m->info->user_name, slen);
di->user_name = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
p += slen;
}
if (m->info->host_name) {
slen = strlen (m->info->host_name) + 1;
memcpy (p, m->info->host_name, slen);
di->host_name = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
p += slen;
}
if (m->info->version) {
slen = strlen (m->info->version) + 1;
memcpy (p, m->info->version, slen);
di->version = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
p += slen;
}
if (m->info->name) {
slen = strlen (m->info->name) + 1;
memcpy (p, m->info->name, slen);
di->name = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
p += slen;
}
if (m->info->props) {
len = pinos_serialize_dict_serialize (p, m->info->props);
di->props = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
}
}
}
static void
connection_add_module_info (PinosConnection *conn, uint32_t dest_id, PinosMessageModuleInfo *m)
{
size_t len, slen;
void *p;
PinosMessageModuleInfo *d;
/* calc len */
len = sizeof (PinosMessageModuleInfo);
if (m->info) {
len += sizeof (PinosModuleInfo);
len += m->info->name ? strlen (m->info->name) + 1 : 0;
len += m->info->filename ? strlen (m->info->filename) + 1 : 0;
len += m->info->args ? strlen (m->info->args) + 1 : 0;
len += pinos_serialize_dict_get_size (m->info->props);
}
p = connection_add_message (conn, dest_id, PINOS_MESSAGE_MODULE_INFO, len);
memcpy (p, m, sizeof (PinosMessageModuleInfo));
d = p;
p = SPA_MEMBER (d, sizeof (PinosMessageModuleInfo), void);
if (m->info) {
PinosModuleInfo *di;
memcpy (p, m->info, sizeof (PinosModuleInfo));
d->info = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
di = p;
p = SPA_MEMBER (p, sizeof (PinosModuleInfo), void);
if (m->info->name) {
slen = strlen (m->info->name) + 1;
memcpy (p, m->info->name, slen);
di->name = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
p += slen;
}
if (m->info->filename) {
slen = strlen (m->info->filename) + 1;
memcpy (p, m->info->filename, slen);
di->filename = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
p += slen;
}
if (m->info->args) {
slen = strlen (m->info->args) + 1;
memcpy (p, m->info->args, slen);
di->args = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
p += slen;
}
if (m->info->props) {
len = pinos_serialize_dict_serialize (p, m->info->props);
di->props = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
}
}
}
static void
connection_add_node_info (PinosConnection *conn, uint32_t dest_id, PinosMessageNodeInfo *m)
{
size_t len, slen;
void *p;
PinosMessageNodeInfo *d;
/* calc len */
len = sizeof (PinosMessageNodeInfo);
if (m->info) {
len += sizeof (PinosNodeInfo);
len += m->info->name ? strlen (m->info->name) + 1 : 0;
len += pinos_serialize_dict_get_size (m->info->props);
}
p = connection_add_message (conn, dest_id, PINOS_MESSAGE_NODE_INFO, len);
memcpy (p, m, sizeof (PinosMessageNodeInfo));
d = p;
p = SPA_MEMBER (d, sizeof (PinosMessageNodeInfo), void);
if (m->info) {
PinosNodeInfo *di;
memcpy (p, m->info, sizeof (PinosNodeInfo));
d->info = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
di = p;
p = SPA_MEMBER (p, sizeof (PinosNodeInfo), void);
if (m->info->name) {
slen = strlen (m->info->name) + 1;
memcpy (p, m->info->name, slen);
di->name = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
p += slen;
}
if (m->info->props) {
len = pinos_serialize_dict_serialize (p, m->info->props);
di->props = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
}
}
}
static void
connection_add_client_info (PinosConnection *conn, uint32_t dest_id, PinosMessageClientInfo *m)
{
size_t len;
void *p;
PinosMessageClientInfo *d;
/* calc len */
len = sizeof (PinosMessageClientInfo);
if (m->info) {
len += sizeof (PinosClientInfo);
len += pinos_serialize_dict_get_size (m->info->props);
}
p = connection_add_message (conn, dest_id, PINOS_MESSAGE_CLIENT_INFO, len);
memcpy (p, m, sizeof (PinosMessageClientInfo));
d = p;
p = SPA_MEMBER (d, sizeof (PinosMessageClientInfo), void);
if (m->info) {
PinosClientInfo *di;
memcpy (p, m->info, sizeof (PinosClientInfo));
d->info = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
di = p;
p = SPA_MEMBER (p, sizeof (PinosClientInfo), void);
if (m->info->props) {
len = pinos_serialize_dict_serialize (p, m->info->props);
di->props = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
}
}
}
static void
connection_add_link_info (PinosConnection *conn, uint32_t dest_id, PinosMessageLinkInfo *m)
{
size_t len;
void *p;
PinosMessageLinkInfo *d;
/* calc len */
len = sizeof (PinosMessageLinkInfo);
if (m->info) {
len += sizeof (PinosLinkInfo);
}
p = connection_add_message (conn, dest_id, PINOS_MESSAGE_LINK_INFO, len);
memcpy (p, m, sizeof (PinosMessageLinkInfo));
d = p;
p = SPA_MEMBER (d, sizeof (PinosMessageLinkInfo), void);
if (m->info) {
memcpy (p, m->info, sizeof (PinosLinkInfo));
d->info = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
} }
} }
@ -761,10 +1067,30 @@ pinos_connection_parse_message (PinosConnection *conn,
memcpy (message, conn->in.data, sizeof (PinosMessageDestroy)); memcpy (message, conn->in.data, sizeof (PinosMessageDestroy));
break; break;
case PINOS_MESSAGE_DESTROY_DONE: case PINOS_MESSAGE_REMOVE_ID:
if (conn->in.size < sizeof (PinosMessageDestroyDone)) if (conn->in.size < sizeof (PinosMessageRemoveId))
return false; return false;
memcpy (message, conn->in.data, sizeof (PinosMessageDestroyDone)); memcpy (message, conn->in.data, sizeof (PinosMessageRemoveId));
break;
case PINOS_MESSAGE_CORE_INFO:
connection_parse_core_info (conn, message);
break;
case PINOS_MESSAGE_MODULE_INFO:
connection_parse_module_info (conn, message);
break;
case PINOS_MESSAGE_NODE_INFO:
connection_parse_node_info (conn, message);
break;
case PINOS_MESSAGE_CLIENT_INFO:
connection_parse_client_info (conn, message);
break;
case PINOS_MESSAGE_LINK_INFO:
connection_parse_link_info (conn, message);
break; break;
/* C -> S */ /* C -> S */
@ -927,11 +1253,30 @@ pinos_connection_add_message (PinosConnection *conn,
memcpy (p, message, sizeof (PinosMessageDestroy)); memcpy (p, message, sizeof (PinosMessageDestroy));
break; break;
case PINOS_MESSAGE_DESTROY_DONE: case PINOS_MESSAGE_REMOVE_ID:
p = connection_add_message (conn, dest_id, type, sizeof (PinosMessageDestroyDone)); p = connection_add_message (conn, dest_id, type, sizeof (PinosMessageRemoveId));
memcpy (p, message, sizeof (PinosMessageDestroyDone)); memcpy (p, message, sizeof (PinosMessageRemoveId));
break; break;
case PINOS_MESSAGE_CORE_INFO:
connection_add_core_info (conn, dest_id, message);
break;
case PINOS_MESSAGE_MODULE_INFO:
connection_add_module_info (conn, dest_id, message);
break;
case PINOS_MESSAGE_NODE_INFO:
connection_add_node_info (conn, dest_id, message);
break;
case PINOS_MESSAGE_CLIENT_INFO:
connection_add_client_info (conn, dest_id, message);
break;
case PINOS_MESSAGE_LINK_INFO:
connection_add_link_info (conn, dest_id, message);
break;
/* C -> S */ /* C -> S */
case PINOS_MESSAGE_NODE_UPDATE: case PINOS_MESSAGE_NODE_UPDATE:

View file

@ -38,6 +38,8 @@ typedef enum {
PINOS_MESSAGE_SYNC, PINOS_MESSAGE_SYNC,
PINOS_MESSAGE_NOTIFY_DONE, PINOS_MESSAGE_NOTIFY_DONE,
PINOS_MESSAGE_GET_REGISTRY, PINOS_MESSAGE_GET_REGISTRY,
PINOS_MESSAGE_REMOVE_ID,
PINOS_MESSAGE_CORE_INFO,
PINOS_MESSAGE_BIND, PINOS_MESSAGE_BIND,
PINOS_MESSAGE_NOTIFY_GLOBAL, PINOS_MESSAGE_NOTIFY_GLOBAL,
@ -50,7 +52,11 @@ typedef enum {
PINOS_MESSAGE_CREATE_CLIENT_NODE_DONE, PINOS_MESSAGE_CREATE_CLIENT_NODE_DONE,
PINOS_MESSAGE_DESTROY, PINOS_MESSAGE_DESTROY,
PINOS_MESSAGE_DESTROY_DONE,
PINOS_MESSAGE_MODULE_INFO,
PINOS_MESSAGE_NODE_INFO,
PINOS_MESSAGE_CLIENT_INFO,
PINOS_MESSAGE_LINK_INFO,
/* client to server */ /* client to server */
PINOS_MESSAGE_NODE_UPDATE, PINOS_MESSAGE_NODE_UPDATE,
@ -78,6 +84,8 @@ typedef enum {
} PinosMessageType; } PinosMessageType;
#include <pinos/client/introspect.h>
/* PINOS_MESSAGE_SYNC */ /* PINOS_MESSAGE_SYNC */
typedef struct { typedef struct {
uint32_t seq; uint32_t seq;
@ -94,6 +102,36 @@ typedef struct {
uint32_t new_id; uint32_t new_id;
} PinosMessageGetRegistry; } PinosMessageGetRegistry;
/* PINOS_MESSAGE_REMOVE_ID */
typedef struct {
uint32_t id;
} PinosMessageRemoveId;
/* PINOS_MESSAGE_CORE_INFO */
typedef struct {
PinosCoreInfo *info;
} PinosMessageCoreInfo;
/* PINOS_MESSAGE_MODULE_INFO */
typedef struct {
PinosModuleInfo *info;
} PinosMessageModuleInfo;
/* PINOS_MESSAGE_NODE_INFO */
typedef struct {
PinosNodeInfo *info;
} PinosMessageNodeInfo;
/* PINOS_MESSAGE_CLIENT_INFO */
typedef struct {
PinosClientInfo *info;
} PinosMessageClientInfo;
/* PINOS_MESSAGE_LINK_INFO */
typedef struct {
PinosLinkInfo *info;
} PinosMessageLinkInfo;
/* PINOS_MESSAGE_BIND */ /* PINOS_MESSAGE_BIND */
typedef struct { typedef struct {
uint32_t id; uint32_t id;
@ -145,12 +183,6 @@ typedef struct {
uint32_t id; uint32_t id;
} PinosMessageDestroy; } PinosMessageDestroy;
/* PINOS_MESSAGE_DESTROY_DONE */
typedef struct {
uint32_t seq;
uint32_t id;
} PinosMessageDestroyDone;
/* PINOS_MESSAGE_NODE_UPDATE */ /* PINOS_MESSAGE_NODE_UPDATE */
typedef struct { typedef struct {
#define PINOS_MESSAGE_NODE_UPDATE_MAX_INPUTS (1 << 0) #define PINOS_MESSAGE_NODE_UPDATE_MAX_INPUTS (1 << 0)

View file

@ -38,7 +38,6 @@ typedef struct {
bool disconnecting; bool disconnecting;
PinosSubscriptionFlags subscribe_mask;
PinosSubscriptionFunc subscribe_func; PinosSubscriptionFunc subscribe_func;
void *subscribe_data; void *subscribe_data;
} PinosContextImpl; } PinosContextImpl;
@ -102,7 +101,8 @@ core_dispatch_func (void *object,
void *message, void *message,
void *data) void *data)
{ {
PinosContext *context = data; PinosContextImpl *impl = data;
PinosContext *this = &impl->this;
switch (type) { switch (type) {
case PINOS_MESSAGE_NOTIFY_DONE: case PINOS_MESSAGE_NOTIFY_DONE:
@ -110,7 +110,142 @@ core_dispatch_func (void *object,
PinosMessageNotifyDone *nd = message; PinosMessageNotifyDone *nd = message;
if (nd->seq == 0) if (nd->seq == 0)
context_set_state (context, PINOS_CONTEXT_STATE_CONNECTED, NULL); context_set_state (this, PINOS_CONTEXT_STATE_CONNECTED, NULL);
break;
}
case PINOS_MESSAGE_REMOVE_ID:
{
PinosMessageRemoveId *m = message;
PinosProxy *proxy;
proxy = pinos_map_lookup (&this->objects, m->id);
if (proxy) {
pinos_log_debug ("context %p: object remove %u", this, m->id);
pinos_map_remove (&this->objects, m->id);
pinos_proxy_destroy (proxy);
}
break;
}
default:
pinos_log_warn ("unhandled message %d", type);
break;
}
return SPA_RESULT_OK;
}
static SpaResult
module_dispatch_func (void *object,
PinosMessageType type,
void *message,
void *data)
{
PinosContextImpl *impl = data;
PinosContext *this = &impl->this;
PinosProxy *proxy = object;
switch (type) {
case PINOS_MESSAGE_MODULE_INFO:
{
PinosMessageModuleInfo *m = message;
PinosSubscriptionEvent event;
pinos_log_debug ("got module info %d", type);
if (proxy->user_data == NULL)
event = PINOS_SUBSCRIPTION_EVENT_NEW;
else
event = PINOS_SUBSCRIPTION_EVENT_CHANGE;
proxy->user_data = pinos_module_info_update (proxy->user_data, m->info);
if (impl->subscribe_func) {
impl->subscribe_func (this,
event,
proxy->type,
proxy->id,
impl->subscribe_data);
}
break;
}
default:
pinos_log_warn ("unhandled message %d", type);
break;
}
return SPA_RESULT_OK;
}
static SpaResult
node_dispatch_func (void *object,
PinosMessageType type,
void *message,
void *data)
{
PinosContextImpl *impl = data;
PinosContext *this = &impl->this;
PinosProxy *proxy = object;
switch (type) {
case PINOS_MESSAGE_NODE_INFO:
{
PinosMessageNodeInfo *m = message;
PinosSubscriptionEvent event;
pinos_log_debug ("got node info %d", type);
if (proxy->user_data == NULL)
event = PINOS_SUBSCRIPTION_EVENT_NEW;
else
event = PINOS_SUBSCRIPTION_EVENT_CHANGE;
proxy->user_data = pinos_node_info_update (proxy->user_data, m->info);
if (impl->subscribe_func) {
impl->subscribe_func (this,
event,
proxy->type,
proxy->id,
impl->subscribe_data);
}
break;
}
default:
pinos_log_warn ("unhandled message %d", type);
break;
}
return SPA_RESULT_OK;
}
static SpaResult
client_dispatch_func (void *object,
PinosMessageType type,
void *message,
void *data)
{
PinosContextImpl *impl = data;
PinosContext *this = &impl->this;
PinosProxy *proxy = object;
switch (type) {
case PINOS_MESSAGE_CLIENT_INFO:
{
PinosMessageClientInfo *m = message;
PinosSubscriptionEvent event;
pinos_log_debug ("got client info %d", type);
if (proxy->user_data == NULL)
event = PINOS_SUBSCRIPTION_EVENT_NEW;
else
event = PINOS_SUBSCRIPTION_EVENT_CHANGE;
proxy->user_data = pinos_client_info_update (proxy->user_data, m->info);
if (impl->subscribe_func) {
impl->subscribe_func (this,
event,
proxy->type,
proxy->id,
impl->subscribe_data);
}
break; break;
} }
default: default:
@ -126,17 +261,61 @@ registry_dispatch_func (void *object,
void *message, void *message,
void *data) void *data)
{ {
PinosContextImpl *impl = data;
PinosContext *this = &impl->this;
switch (type) { switch (type) {
case PINOS_MESSAGE_NOTIFY_GLOBAL: case PINOS_MESSAGE_NOTIFY_GLOBAL:
{ {
PinosMessageNotifyGlobal *ng = message; PinosMessageNotifyGlobal *ng = message;
PinosProxy *proxy = NULL;
pinos_log_debug ("got global %u %s", ng->id, ng->type); pinos_log_debug ("got global %u %s", ng->id, ng->type);
if (!strcmp (ng->type, PINOS_NODE_URI)) {
proxy = pinos_proxy_new (this,
SPA_ID_INVALID,
this->uri.node);
proxy->dispatch_func = node_dispatch_func;
proxy->dispatch_data = impl;
} else if (!strcmp (ng->type, PINOS_MODULE_URI)) {
proxy = pinos_proxy_new (this,
SPA_ID_INVALID,
this->uri.module);
proxy->dispatch_func = module_dispatch_func;
proxy->dispatch_data = impl;
} else if (!strcmp (ng->type, PINOS_CLIENT_URI)) {
proxy = pinos_proxy_new (this,
SPA_ID_INVALID,
this->uri.client);
proxy->dispatch_func = client_dispatch_func;
proxy->dispatch_data = impl;
} else if (!strcmp (ng->type, PINOS_LINK_URI)) {
}
if (proxy) {
PinosMessageBind m;
m.id = ng->id;
m.new_id = proxy->id;
pinos_proxy_send_message (this->registry_proxy,
PINOS_MESSAGE_BIND,
&m,
true);
}
break; break;
} }
case PINOS_MESSAGE_NOTIFY_GLOBAL_REMOVE: case PINOS_MESSAGE_NOTIFY_GLOBAL_REMOVE:
{ {
PinosMessageNotifyGlobalRemove *ng = message; PinosMessageNotifyGlobalRemove *ng = message;
pinos_log_debug ("got global remove %u", ng->id); pinos_log_debug ("got global remove %u", ng->id);
if (impl->subscribe_func) {
impl->subscribe_func (this,
PINOS_SUBSCRIPTION_EVENT_REMOVE,
SPA_ID_INVALID,
ng->id,
impl->subscribe_data);
}
break; break;
} }
default: default:
@ -146,19 +325,6 @@ registry_dispatch_func (void *object,
return SPA_RESULT_OK; return SPA_RESULT_OK;
} }
static PinosProxy *
find_proxy (PinosContext *context,
uint32_t id)
{
PinosProxy *p;
spa_list_for_each (p, &context->proxy_list, link) {
if (p->id == id)
return p;
}
return NULL;
}
static void static void
on_context_data (SpaSource *source, on_context_data (SpaSource *source,
int fd, int fd,
@ -190,11 +356,15 @@ on_context_data (SpaSource *source,
continue; continue;
} }
proxy = find_proxy (this, id); proxy = pinos_map_lookup (&this->objects, id);
if (proxy == NULL) { if (proxy == NULL) {
pinos_log_error ("context %p: could not find proxy %u", this, id); pinos_log_error ("context %p: could not find proxy %u", this, id);
continue; continue;
} }
if (proxy->dispatch_func == NULL) {
pinos_log_error ("context %p: no dispatch function for proxy %u", this, id);
continue;
}
proxy->dispatch_func (proxy, type, p, proxy->dispatch_data); proxy->dispatch_func (proxy, type, p, proxy->dispatch_data);
} }
@ -250,6 +420,8 @@ pinos_context_new (PinosLoop *loop,
pinos_fill_context_properties (properties); pinos_fill_context_properties (properties);
this->properties = properties; this->properties = properties;
pinos_uri_init (&this->uri);
this->loop = loop; this->loop = loop;
this->state = PINOS_CONTEXT_STATE_UNCONNECTED; this->state = PINOS_CONTEXT_STATE_UNCONNECTED;
@ -365,15 +537,15 @@ pinos_context_connect (PinosContext *context)
context->core_proxy = pinos_proxy_new (context, context->core_proxy = pinos_proxy_new (context,
SPA_ID_INVALID, SPA_ID_INVALID,
0); context->uri.core);
context->core_proxy->dispatch_func = core_dispatch_func; context->core_proxy->dispatch_func = core_dispatch_func;
context->core_proxy->dispatch_data = context; context->core_proxy->dispatch_data = impl;
context->registry_proxy = pinos_proxy_new (context, context->registry_proxy = pinos_proxy_new (context,
SPA_ID_INVALID, SPA_ID_INVALID,
0); context->uri.registry);
context->registry_proxy->dispatch_func = registry_dispatch_func; context->registry_proxy->dispatch_func = registry_dispatch_func;
context->registry_proxy->dispatch_data = context; context->registry_proxy->dispatch_data = impl;
grm.seq = 0; grm.seq = 0;
grm.new_id = context->registry_proxy->id; grm.new_id = context->registry_proxy->id;
@ -409,23 +581,84 @@ pinos_context_disconnect (PinosContext *context)
void void
pinos_context_subscribe (PinosContext *context, pinos_context_subscribe (PinosContext *context,
PinosSubscriptionFlags mask,
PinosSubscriptionFunc func, PinosSubscriptionFunc func,
void *data) void *data)
{ {
PinosContextImpl *impl = SPA_CONTAINER_OF (context, PinosContextImpl, this); PinosContextImpl *impl = SPA_CONTAINER_OF (context, PinosContextImpl, this);
impl->subscribe_mask = mask;
impl->subscribe_func = func; impl->subscribe_func = func;
impl->subscribe_data = data; impl->subscribe_data = data;
} }
void void
pinos_context_get_daemon_info (PinosContext *context, pinos_context_get_core_info (PinosContext *context,
PinosDaemonInfoCallback cb, PinosCoreInfoCallback cb,
void *user_data) void *user_data)
{ {
cb (context, SPA_RESULT_OK, NULL, user_data); PinosProxy *proxy;
proxy = pinos_map_lookup (&context->objects, 0);
if (proxy == NULL) {
cb (context, SPA_RESULT_INVALID_OBJECT_ID, NULL, user_data);
} else if (proxy->type == context->uri.core && proxy->user_data) {
PinosCoreInfo *info = proxy->user_data;
cb (context, SPA_RESULT_OK, info, user_data);
info->change_mask = 0;
}
cb (context, SPA_RESULT_ENUM_END, NULL, user_data);
}
typedef void (*ListFunc) (PinosContext *, SpaResult, void *, void *);
static void
do_list (PinosContext *context,
uint32_t type,
ListFunc cb,
void *user_data)
{
PinosMapItem *item;
pinos_array_for_each (item, &context->objects.items) {
PinosProxy *proxy;
if (pinos_map_item_is_free (item))
continue;
proxy = item->data;
if (proxy->type != type)
continue;
cb (context, SPA_RESULT_OK, proxy->user_data, user_data);
}
cb (context, SPA_RESULT_ENUM_END, NULL, user_data);
}
void
pinos_context_list_module_info (PinosContext *context,
PinosModuleInfoCallback cb,
void *user_data)
{
do_list (context, context->uri.module, (ListFunc) cb, user_data);
}
void
pinos_context_get_module_info_by_id (PinosContext *context,
uint32_t id,
PinosModuleInfoCallback cb,
void *user_data)
{
PinosProxy *proxy;
proxy = pinos_map_lookup (&context->objects, id);
if (proxy == NULL) {
cb (context, SPA_RESULT_INVALID_OBJECT_ID, NULL, user_data);
} else if (proxy->type == context->uri.module && proxy->user_data) {
PinosModuleInfo *info = proxy->user_data;
cb (context, SPA_RESULT_OK, info, user_data);
info->change_mask = 0;
}
cb (context, SPA_RESULT_ENUM_END, NULL, user_data);
} }
void void
@ -433,7 +666,7 @@ pinos_context_list_client_info (PinosContext *context,
PinosClientInfoCallback cb, PinosClientInfoCallback cb,
void *user_data) void *user_data)
{ {
cb (context, SPA_RESULT_OK, NULL, user_data); do_list (context, context->uri.client, (ListFunc) cb, user_data);
} }
void void
@ -442,7 +675,17 @@ pinos_context_get_client_info_by_id (PinosContext *context,
PinosClientInfoCallback cb, PinosClientInfoCallback cb,
void *user_data) void *user_data)
{ {
cb (context, SPA_RESULT_OK, NULL, user_data); PinosProxy *proxy;
proxy = pinos_map_lookup (&context->objects, id);
if (proxy == NULL) {
cb (context, SPA_RESULT_INVALID_OBJECT_ID, NULL, user_data);
} else if (proxy->type == context->uri.client && proxy->user_data) {
PinosClientInfo *info = proxy->user_data;
cb (context, SPA_RESULT_OK, info, user_data);
info->change_mask = 0;
}
cb (context, SPA_RESULT_ENUM_END, NULL, user_data);
} }
void void
@ -450,7 +693,7 @@ pinos_context_list_node_info (PinosContext *context,
PinosNodeInfoCallback cb, PinosNodeInfoCallback cb,
void *user_data) void *user_data)
{ {
cb (context, SPA_RESULT_OK, NULL, user_data); do_list (context, context->uri.node, (ListFunc) cb, user_data);
} }
void void
@ -459,7 +702,17 @@ pinos_context_get_node_info_by_id (PinosContext *context,
PinosNodeInfoCallback cb, PinosNodeInfoCallback cb,
void *user_data) void *user_data)
{ {
cb (context, SPA_RESULT_OK, NULL, user_data); PinosProxy *proxy;
proxy = pinos_map_lookup (&context->objects, id);
if (proxy == NULL) {
cb (context, SPA_RESULT_INVALID_OBJECT_ID, NULL, user_data);
} else if (proxy->type == context->uri.node && proxy->user_data) {
PinosNodeInfo *info = proxy->user_data;
cb (context, SPA_RESULT_OK, info, user_data);
info->change_mask = 0;
}
cb (context, SPA_RESULT_ENUM_END, NULL, user_data);
} }
void void
@ -467,7 +720,7 @@ pinos_context_list_link_info (PinosContext *context,
PinosLinkInfoCallback cb, PinosLinkInfoCallback cb,
void *user_data) void *user_data)
{ {
cb (context, SPA_RESULT_OK, NULL, user_data); do_list (context, context->uri.link, (ListFunc) cb, user_data);
} }
void void
@ -476,5 +729,15 @@ pinos_context_get_link_info_by_id (PinosContext *context,
PinosLinkInfoCallback cb, PinosLinkInfoCallback cb,
void *user_data) void *user_data)
{ {
cb (context, SPA_RESULT_OK, NULL, user_data); PinosProxy *proxy;
proxy = pinos_map_lookup (&context->objects, id);
if (proxy == NULL) {
cb (context, SPA_RESULT_INVALID_OBJECT_ID, NULL, user_data);
} else if (proxy->type == context->uri.link && proxy->user_data) {
PinosLinkInfo *info = proxy->user_data;
cb (context, SPA_RESULT_OK, info, user_data);
info->change_mask = 0;
}
cb (context, SPA_RESULT_ENUM_END, NULL, user_data);
} }

View file

@ -28,10 +28,9 @@ typedef struct _PinosContext PinosContext;
#include <pinos/client/map.h> #include <pinos/client/map.h>
#include <pinos/client/loop.h> #include <pinos/client/loop.h>
#include <pinos/client/subscribe.h>
#include <pinos/client/properties.h> #include <pinos/client/properties.h>
#include <pinos/client/connection.h>
#include <pinos/client/proxy.h> #include <pinos/client/proxy.h>
#include <pinos/client/uri.h>
/** /**
* PinosContextState: * PinosContextState:
@ -60,6 +59,8 @@ struct _PinosContext {
char *name; char *name;
PinosProperties *properties; PinosProperties *properties;
PinosURI uri;
PinosLoop *loop; PinosLoop *loop;
PinosProxy *core_proxy; PinosProxy *core_proxy;

View file

@ -103,3 +103,177 @@ pinos_link_state_as_string (PinosLinkState state)
} }
return "invalid-state"; return "invalid-state";
} }
static void
pinos_spa_dict_destroy (SpaDict *dict)
{
SpaDictItem *item;
spa_dict_for_each (item, dict) {
free ((void *)item->key);
free ((void *)item->value);
}
free (dict->items);
free (dict);
}
static SpaDict *
pinos_spa_dict_copy (SpaDict *dict)
{
SpaDict *copy;
unsigned int i;
if (dict == NULL)
return NULL;
copy = calloc (1, sizeof (SpaDict));
copy->items = calloc (dict->n_items, sizeof (SpaDictItem));
copy->n_items = dict->n_items;
for (i = 0; i < dict->n_items; i++) {
copy->items[i].key = strdup (dict->items[i].key);
copy->items[i].value = strdup (dict->items[i].value);
}
return copy;
}
PinosNodeInfo *
pinos_node_info_update (PinosNodeInfo *info,
const PinosNodeInfo *update)
{
uint64_t change_mask;
if (update == NULL)
return info;
if (info == NULL) {
info = calloc (1, sizeof (PinosNodeInfo));
change_mask = ~0;
} else {
change_mask = info->change_mask | update->change_mask;
}
info->id = update->id;
info->change_mask = change_mask;
if (update->change_mask & (1 << 0)) {
if (info->name)
free ((void*)info->name);
info->name = update->name ? strdup (update->name) : NULL;
}
if (update->change_mask & (1 << 1)) {
info->state = update->state;
}
if (update->change_mask & (1 << 2)) {
if (info->props)
pinos_spa_dict_destroy (info->props);
info->props = pinos_spa_dict_copy (update->props);
}
return info;
}
void
pinos_node_info_free (PinosNodeInfo *info)
{
if (info == NULL)
return;
if (info->name)
free ((void*)info->name);
if (info->props)
pinos_spa_dict_destroy (info->props);
free (info);
}
PinosModuleInfo *
pinos_module_info_update (PinosModuleInfo *info,
const PinosModuleInfo *update)
{
uint64_t change_mask;
if (update == NULL)
return info;
if (info == NULL) {
info = calloc (1, sizeof (PinosModuleInfo));
change_mask = ~0;
} else {
change_mask = info->change_mask | update->change_mask;
}
info->id = update->id;
info->change_mask = change_mask;
if (update->change_mask & (1 << 0)) {
if (info->name)
free ((void*)info->name);
info->name = update->name ? strdup (update->name) : NULL;
}
if (update->change_mask & (1 << 1)) {
if (info->filename)
free ((void*)info->filename);
info->filename = update->filename ? strdup (update->filename) : NULL;
}
if (update->change_mask & (1 << 2)) {
if (info->args)
free ((void*)info->args);
info->args = update->args ? strdup (update->args) : NULL;
}
if (update->change_mask & (1 << 3)) {
if (info->props)
pinos_spa_dict_destroy (info->props);
info->props = pinos_spa_dict_copy (update->props);
}
return info;
}
void
pinos_module_info_free (PinosModuleInfo *info)
{
if (info == NULL)
return;
if (info->name)
free ((void*)info->name);
if (info->filename)
free ((void*)info->filename);
if (info->args)
free ((void*)info->args);
if (info->props)
pinos_spa_dict_destroy (info->props);
free (info);
}
PinosClientInfo *
pinos_client_info_update (PinosClientInfo *info,
const PinosClientInfo *update)
{
uint64_t change_mask;
if (update == NULL)
return info;
if (info == NULL) {
info = calloc (1, sizeof (PinosClientInfo));
change_mask = ~0;
} else {
change_mask = info->change_mask | update->change_mask;
}
info->id = update->id;
info->change_mask = change_mask;
if (update->change_mask & (1 << 0)) {
if (info->props)
pinos_spa_dict_destroy (info->props);
info->props = pinos_spa_dict_copy (update->props);
}
return info;
}
void
pinos_client_info_free (PinosClientInfo *info)
{
if (info == NULL)
return;
if (info->props)
pinos_spa_dict_destroy (info->props);
free (info);
}

View file

@ -26,6 +26,19 @@
extern "C" { extern "C" {
#endif #endif
typedef enum _PinosNodeState PinosNodeState;
typedef enum _PinosDirection PinosDirection;
typedef enum _PinosLinkState PinosLinkState;
typedef struct _PinosCoreInfo PinosCoreInfo;
typedef struct _PinosModuleInfo PinosModuleInfo;
typedef struct _PinosClientInfo PinosClientInfo;
typedef struct _PinosNodeInfo PinosNodeInfo;
typedef struct _PinosLinkInfo PinosLinkInfo;
#include <pinos/client/context.h>
#include <pinos/client/properties.h>
/** /**
* PinosNodeState: * PinosNodeState:
* @PINOS_NODE_STATE_ERROR: the node is in error * @PINOS_NODE_STATE_ERROR: the node is in error
@ -40,14 +53,14 @@ extern "C" {
* *
* The different node states * The different node states
*/ */
typedef enum { enum _PinosNodeState {
PINOS_NODE_STATE_ERROR = -1, PINOS_NODE_STATE_ERROR = -1,
PINOS_NODE_STATE_CREATING = 0, PINOS_NODE_STATE_CREATING = 0,
PINOS_NODE_STATE_SUSPENDED = 1, PINOS_NODE_STATE_SUSPENDED = 1,
PINOS_NODE_STATE_INITIALIZING = 2, PINOS_NODE_STATE_INITIALIZING = 2,
PINOS_NODE_STATE_IDLE = 3, PINOS_NODE_STATE_IDLE = 3,
PINOS_NODE_STATE_RUNNING = 4, PINOS_NODE_STATE_RUNNING = 4,
} PinosNodeState; };
const char * pinos_node_state_as_string (PinosNodeState state); const char * pinos_node_state_as_string (PinosNodeState state);
@ -59,11 +72,11 @@ const char * pinos_node_state_as_string (PinosNodeState state);
* *
* The direction of a port * The direction of a port
*/ */
typedef enum { enum _PinosDirection {
PINOS_DIRECTION_INVALID = SPA_DIRECTION_INVALID, PINOS_DIRECTION_INVALID = SPA_DIRECTION_INVALID,
PINOS_DIRECTION_INPUT = SPA_DIRECTION_INPUT, PINOS_DIRECTION_INPUT = SPA_DIRECTION_INPUT,
PINOS_DIRECTION_OUTPUT = SPA_DIRECTION_OUTPUT PINOS_DIRECTION_OUTPUT = SPA_DIRECTION_OUTPUT
} PinosDirection; };
const char * pinos_direction_as_string (PinosDirection direction); const char * pinos_direction_as_string (PinosDirection direction);
@ -79,7 +92,7 @@ const char * pinos_direction_as_string (PinosDirection direction);
* *
* The different link states * The different link states
*/ */
typedef enum { enum _PinosLinkState {
PINOS_LINK_STATE_ERROR = -2, PINOS_LINK_STATE_ERROR = -2,
PINOS_LINK_STATE_UNLINKED = -1, PINOS_LINK_STATE_UNLINKED = -1,
PINOS_LINK_STATE_INIT = 0, PINOS_LINK_STATE_INIT = 0,
@ -87,28 +100,25 @@ typedef enum {
PINOS_LINK_STATE_ALLOCATING = 2, PINOS_LINK_STATE_ALLOCATING = 2,
PINOS_LINK_STATE_PAUSED = 3, PINOS_LINK_STATE_PAUSED = 3,
PINOS_LINK_STATE_RUNNING = 4, PINOS_LINK_STATE_RUNNING = 4,
} PinosLinkState; };
const char * pinos_link_state_as_string (PinosLinkState state); const char * pinos_link_state_as_string (PinosLinkState state);
#include <pinos/client/context.h>
#include <pinos/client/properties.h>
/** /**
* PinosDaemonInfo: * PinosCoreInfo:
* @id: generic id of the daemon * @id: generic id of the core
* @change_mask: bitfield of changed fields since last call * @change_mask: bitfield of changed fields since last call
* @user_name: name of the user that started the daemon * @user_name: name of the user that started the core
* @host_name: name of the machine the daemon is running on * @host_name: name of the machine the core is running on
* @version: version of the daemon * @version: version of the core
* @name: name of the daemon * @name: name of the core
* @cookie: a random cookie for identifying this instance of Pinos * @cookie: a random cookie for identifying this instance of Pinos
* @properties: extra properties * @props: extra properties
* *
* The daemon information. Extra information can be added in later * The core information. Extra information can be added in later
* versions. * versions.
*/ */
typedef struct { struct _PinosCoreInfo {
uint32_t id; uint32_t id;
uint64_t change_mask; uint64_t change_mask;
const char *user_name; const char *user_name;
@ -116,41 +126,93 @@ typedef struct {
const char *version; const char *version;
const char *name; const char *name;
uint32_t cookie; uint32_t cookie;
PinosProperties *properties; SpaDict *props;
} PinosDaemonInfo; };
PinosCoreInfo * pinos_core_info_update (PinosCoreInfo *info,
const PinosCoreInfo *update);
void pinos_core_info_free (PinosCoreInfo *info);
/**
* PinosCoreInfoCallback:
* @c: a #PinosContext
* @info: a #PinosCoreInfo
* @user_data: user data
*
* Callback with information about the Pinos core in @info.
*/
typedef void (*PinosCoreInfoCallback) (PinosContext *c,
SpaResult res,
const PinosCoreInfo *info,
void *user_data);
void pinos_context_get_core_info (PinosContext *context,
PinosCoreInfoCallback cb,
void *user_data);
/**
* PinosModuleInfo:
* @id: generic id of the module
* @change_mask: bitfield of changed fields since last call
* @props: extra properties
*
* The module information. Extra information can be added in later
* versions.
*/
struct _PinosModuleInfo {
uint32_t id;
uint64_t change_mask;
const char *name;
const char *filename;
const char *args;
SpaDict *props;
};
PinosModuleInfo * pinos_module_info_update (PinosModuleInfo *info,
const PinosModuleInfo *update);
void pinos_module_info_free (PinosModuleInfo *info);
/** /**
* PinosDaemonInfoCallback: * PinosModuleInfoCallback:
* @c: a #PinosContext * @c: a #PinosContext
* @info: a #PinosDaemonInfo * @info: a #PinosModuleInfo
* @user_data: user data * @user_data: user data
* *
* Callback with information about the Pinos daemon in @info. * Callback with information about the Pinos module in @info.
*/ */
typedef void (*PinosDaemonInfoCallback) (PinosContext *c, typedef void (*PinosModuleInfoCallback) (PinosContext *c,
SpaResult res, SpaResult res,
const PinosDaemonInfo *info, const PinosModuleInfo *info,
void *user_data); void *user_data);
void pinos_context_get_daemon_info (PinosContext *context, void pinos_context_list_module_info (PinosContext *context,
PinosDaemonInfoCallback cb, PinosModuleInfoCallback cb,
void *user_data); void *user_data);
void pinos_context_get_module_info_by_id (PinosContext *context,
uint32_t id,
PinosModuleInfoCallback cb,
void *user_data);
/** /**
* PinosClientInfo: * PinosClientInfo:
* @id: generic id of the client * @id: generic id of the client
* @change_mask: bitfield of changed fields since last call * @change_mask: bitfield of changed fields since last call
* @properties: extra properties * @props: extra properties
* *
* The client information. Extra information can be added in later * The client information. Extra information can be added in later
* versions. * versions.
*/ */
typedef struct { struct _PinosClientInfo {
uint32_t id; uint32_t id;
uint64_t change_mask; uint64_t change_mask;
PinosProperties *properties; SpaDict *props;
} PinosClientInfo; };
PinosClientInfo * pinos_client_info_update (PinosClientInfo *info,
const PinosClientInfo *update);
void pinos_client_info_free (PinosClientInfo *info);
/** /**
* PinosClientInfoCallback: * PinosClientInfoCallback:
@ -178,19 +240,23 @@ void pinos_context_get_client_info_by_id (PinosContext *co
* @id: generic id of the node * @id: generic id of the node
* @change_mask: bitfield of changed fields since last call * @change_mask: bitfield of changed fields since last call
* @name: name the node, suitable for display * @name: name the node, suitable for display
* @properties: the properties of the node * @props: the properties of the node
* @state: the current state of the node * @state: the current state of the node
* *
* The node information. Extra information can be added in later * The node information. Extra information can be added in later
* versions. * versions.
*/ */
typedef struct { struct _PinosNodeInfo {
uint32_t id; uint32_t id;
uint64_t change_mask; uint64_t change_mask;
const char *name; const char *name;
PinosProperties *properties;
PinosNodeState state; PinosNodeState state;
} PinosNodeInfo; SpaDict *props;
};
PinosNodeInfo * pinos_node_info_update (PinosNodeInfo *info,
const PinosNodeInfo *update);
void pinos_node_info_free (PinosNodeInfo *info);
/** /**
* PinosNodeInfoCallback: * PinosNodeInfoCallback:
@ -226,14 +292,14 @@ void pinos_context_get_node_info_by_id (PinosContext *cont
* The link information. Extra information can be added in later * The link information. Extra information can be added in later
* versions. * versions.
*/ */
typedef struct { struct _PinosLinkInfo {
uint32_t id; uint32_t id;
uint64_t change_mask; uint64_t change_mask;
uint32_t output_node_id; uint32_t output_node_id;
uint32_t output_port_id; uint32_t output_port_id;
uint32_t input_node_id; uint32_t input_node_id;
uint32_t input_port_id; uint32_t input_port_id;
} PinosLinkInfo; };
/** /**

View file

@ -14,6 +14,7 @@ pinos_headers = [
'subscribe.h', 'subscribe.h',
'thread-mainloop.h', 'thread-mainloop.h',
'transport.h', 'transport.h',
'uri.h',
'utils.h', 'utils.h',
] ]
@ -33,6 +34,7 @@ pinos_sources = [
'rtkit.c', 'rtkit.c',
'thread-mainloop.c', 'thread-mainloop.c',
'transport.c', 'transport.c',
'uri.c',
'utils.c', 'utils.c',
] ]

View file

@ -21,37 +21,40 @@
#include "pinos/client/properties.h" #include "pinos/client/properties.h"
typedef struct { typedef struct {
char *key; PinosProperties this;
char *value;
} PropItem;
struct _PinosProperties {
PinosArray items; PinosArray items;
}; } PinosPropertiesImpl;
static void static void
add_func (PinosProperties *props, char *key, char *value) add_func (PinosProperties *this, char *key, char *value)
{ {
PropItem *item; SpaDictItem *item;
item = pinos_array_add (&props->items, sizeof (PropItem)); PinosPropertiesImpl *impl = SPA_CONTAINER_OF (this, PinosPropertiesImpl, this);
item = pinos_array_add (&impl->items, sizeof (SpaDictItem));
item->key = key; item->key = key;
item->value = value; item->value = value;
this->dict.items = impl->items.data;
this->dict.n_items = pinos_array_get_len (&impl->items, SpaDictItem);
} }
static void static void
clear_item (PropItem *item) clear_item (SpaDictItem *item)
{ {
free (item->key); free ((char*)item->key);
free (item->value); free ((char*)item->value);
} }
static int static int
find_index (PinosProperties *props, const char *key) find_index (PinosProperties *this, const char *key)
{ {
int i, len = pinos_array_get_len (&props->items, PropItem); PinosPropertiesImpl *impl = SPA_CONTAINER_OF (this, PinosPropertiesImpl, this);
int i, len = pinos_array_get_len (&impl->items, SpaDictItem);
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
PropItem *item = pinos_array_get_unchecked (&props->items, i, PropItem); SpaDictItem *item = pinos_array_get_unchecked (&impl->items, i, SpaDictItem);
if (strcmp (item->key, key) == 0) if (strcmp (item->key, key) == 0)
return i; return i;
} }
@ -70,22 +73,22 @@ find_index (PinosProperties *props, const char *key)
PinosProperties * PinosProperties *
pinos_properties_new (const char *key, ...) pinos_properties_new (const char *key, ...)
{ {
PinosProperties *props; PinosPropertiesImpl *impl;
va_list varargs; va_list varargs;
const char *value; const char *value;
props = calloc (1, sizeof (PinosProperties)); impl = calloc (1, sizeof (PinosPropertiesImpl));
pinos_array_init (&props->items); pinos_array_init (&impl->items);
va_start (varargs, key); va_start (varargs, key);
while (key != NULL) { while (key != NULL) {
value = va_arg (varargs, char *); value = va_arg (varargs, char *);
add_func (props, strdup (key), strdup (value)); add_func (&impl->this, strdup (key), strdup (value));
key = va_arg (varargs, char *); key = va_arg (varargs, char *);
} }
va_end (varargs); va_end (varargs);
return props; return &impl->this;
} }
/** /**
@ -99,11 +102,12 @@ pinos_properties_new (const char *key, ...)
PinosProperties * PinosProperties *
pinos_properties_copy (PinosProperties *properties) pinos_properties_copy (PinosProperties *properties)
{ {
PinosPropertiesImpl *impl = SPA_CONTAINER_OF (properties, PinosPropertiesImpl, this);
PinosProperties *copy; PinosProperties *copy;
PropItem *item; SpaDictItem *item;
copy = pinos_properties_new (NULL, NULL); copy = pinos_properties_new (NULL, NULL);
pinos_array_for_each (item, &properties->items) pinos_array_for_each (item, &impl->items)
add_func (copy, strdup (item->key), strdup (item->value)); add_func (copy, strdup (item->key), strdup (item->value));
return copy; return copy;
@ -145,13 +149,14 @@ pinos_properties_merge (PinosProperties *oldprops,
void void
pinos_properties_free (PinosProperties *properties) pinos_properties_free (PinosProperties *properties)
{ {
PropItem *item; PinosPropertiesImpl *impl = SPA_CONTAINER_OF (properties, PinosPropertiesImpl, this);
SpaDictItem *item;
pinos_array_for_each (item, &properties->items) pinos_array_for_each (item, &impl->items)
clear_item (item); clear_item (item);
pinos_array_clear (&properties->items); pinos_array_clear (&impl->items);
free (properties); free (impl);
} }
static void static void
@ -159,21 +164,22 @@ do_replace (PinosProperties *properties,
char *key, char *key,
char *value) char *value)
{ {
PinosPropertiesImpl *impl = SPA_CONTAINER_OF (properties, PinosPropertiesImpl, this);
int index = find_index (properties, key); int index = find_index (properties, key);
if (index == -1) { if (index == -1) {
add_func (properties, key, value); add_func (properties, key, value);
} else { } else {
PropItem *item = pinos_array_get_unchecked (&properties->items, index, PropItem); SpaDictItem *item = pinos_array_get_unchecked (&impl->items, index, SpaDictItem);
clear_item (item); clear_item (item);
if (value == NULL) { if (value == NULL) {
PropItem *other = pinos_array_get_unchecked (&properties->items, SpaDictItem *other = pinos_array_get_unchecked (&impl->items,
pinos_array_get_len (&properties->items, PropItem) - 1, pinos_array_get_len (&impl->items, SpaDictItem) - 1,
PropItem); SpaDictItem);
item->key = other->key; item->key = other->key;
item->value = other->value; item->value = other->value;
properties->items.size -= sizeof (PropItem); impl->items.size -= sizeof (SpaDictItem);
} else { } else {
item->key = key; item->key = key;
item->value = value; item->value = value;
@ -238,12 +244,13 @@ const char *
pinos_properties_get (PinosProperties *properties, pinos_properties_get (PinosProperties *properties,
const char *key) const char *key)
{ {
PinosPropertiesImpl *impl = SPA_CONTAINER_OF (properties, PinosPropertiesImpl, this);
int index = find_index (properties, key); int index = find_index (properties, key);
if (index == -1) if (index == -1)
return NULL; return NULL;
return pinos_array_get_unchecked (&properties->items, index, PropItem)->value; return pinos_array_get_unchecked (&impl->items, index, SpaDictItem)->value;
} }
/** /**
@ -264,6 +271,7 @@ const char *
pinos_properties_iterate (PinosProperties *properties, pinos_properties_iterate (PinosProperties *properties,
void **state) void **state)
{ {
PinosPropertiesImpl *impl = SPA_CONTAINER_OF (properties, PinosPropertiesImpl, this);
unsigned int index; unsigned int index;
if (*state == NULL) if (*state == NULL)
@ -271,10 +279,10 @@ pinos_properties_iterate (PinosProperties *properties,
else else
index = SPA_PTR_TO_INT (*state); index = SPA_PTR_TO_INT (*state);
if (!pinos_array_check_index (&properties->items, index, PropItem)) if (!pinos_array_check_index (&impl->items, index, SpaDictItem))
return NULL; return NULL;
*state = SPA_INT_TO_PTR (index + 1); *state = SPA_INT_TO_PTR (index + 1);
return pinos_array_get_unchecked (&properties->items, index, PropItem)->key; return pinos_array_get_unchecked (&impl->items, index, SpaDictItem)->key;
} }

View file

@ -26,6 +26,10 @@ extern "C" {
typedef struct _PinosProperties PinosProperties; typedef struct _PinosProperties PinosProperties;
struct _PinosProperties {
SpaDict dict;
};
PinosProperties * pinos_properties_new (const char *key, ...); PinosProperties * pinos_properties_new (const char *key, ...);
PinosProperties * pinos_properties_copy (PinosProperties *properties); PinosProperties * pinos_properties_copy (PinosProperties *properties);
PinosProperties * pinos_properties_merge (PinosProperties *oldprops, PinosProperties * pinos_properties_merge (PinosProperties *oldprops,

View file

@ -63,12 +63,12 @@ pinos_proxy_destroy (PinosProxy *proxy)
SpaResult SpaResult
pinos_proxy_send_message (PinosProxy *proxy, pinos_proxy_send_message (PinosProxy *proxy,
PinosMessageType type, uint32_t opcode,
void *message, void *message,
bool flush) bool flush)
{ {
if (proxy->send_func) if (proxy->send_func)
return proxy->send_func (proxy, proxy->id, type, message, flush, proxy->send_data); return proxy->send_func (proxy, proxy->id, opcode, message, flush, proxy->send_data);
pinos_log_error ("proxy %p: send func not implemented", proxy); pinos_log_error ("proxy %p: send func not implemented", proxy);

View file

@ -24,21 +24,20 @@
extern "C" { extern "C" {
#endif #endif
#include <pinos/client/connection.h>
typedef struct _PinosProxy PinosProxy; typedef struct _PinosProxy PinosProxy;
typedef SpaResult (*PinosSendFunc) (void *object, typedef SpaResult (*PinosSendFunc) (void *object,
uint32_t id, uint32_t id,
PinosMessageType type, uint32_t opcode,
void *message, void *message,
bool flush, bool flush,
void *data); void *data);
typedef SpaResult (*PinosDispatchFunc) (void *object, typedef SpaResult (*PinosDispatchFunc) (void *object,
PinosMessageType type, uint32_t opcode,
void *message, void *message,
void *data); void *data);
#include <pinos/client/connection.h>
#include <pinos/client/context.h> #include <pinos/client/context.h>
struct _PinosProxy { struct _PinosProxy {
@ -53,6 +52,8 @@ struct _PinosProxy {
PinosDispatchFunc dispatch_func; PinosDispatchFunc dispatch_func;
void *dispatch_data; void *dispatch_data;
void *user_data;
PINOS_SIGNAL (destroy_signal, (PinosListener *listener, PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosProxy *proxy)); PinosProxy *proxy));
}; };
@ -63,7 +64,7 @@ PinosProxy * pinos_proxy_new (PinosContext *contex
void pinos_proxy_destroy (PinosProxy *proxy); void pinos_proxy_destroy (PinosProxy *proxy);
SpaResult pinos_proxy_send_message (PinosProxy *proxy, SpaResult pinos_proxy_send_message (PinosProxy *proxy,
PinosMessageType type, uint32_t opcode,
void *message, void *message,
bool flush); bool flush);

View file

@ -610,13 +610,18 @@ stream_dispatch_func (void *object,
case PINOS_MESSAGE_GET_REGISTRY: case PINOS_MESSAGE_GET_REGISTRY:
case PINOS_MESSAGE_BIND: case PINOS_MESSAGE_BIND:
case PINOS_MESSAGE_DESTROY: case PINOS_MESSAGE_DESTROY:
case PINOS_MESSAGE_DESTROY_DONE: case PINOS_MESSAGE_REMOVE_ID:
case PINOS_MESSAGE_CREATE_NODE: case PINOS_MESSAGE_CREATE_NODE:
case PINOS_MESSAGE_CREATE_CLIENT_NODE: case PINOS_MESSAGE_CREATE_CLIENT_NODE:
case PINOS_MESSAGE_NODE_UPDATE: case PINOS_MESSAGE_NODE_UPDATE:
case PINOS_MESSAGE_PORT_UPDATE: case PINOS_MESSAGE_PORT_UPDATE:
case PINOS_MESSAGE_PORT_STATUS_CHANGE: case PINOS_MESSAGE_PORT_STATUS_CHANGE:
case PINOS_MESSAGE_NODE_STATE_CHANGE: case PINOS_MESSAGE_NODE_STATE_CHANGE:
case PINOS_MESSAGE_CORE_INFO:
case PINOS_MESSAGE_MODULE_INFO:
case PINOS_MESSAGE_NODE_INFO:
case PINOS_MESSAGE_CLIENT_INFO:
case PINOS_MESSAGE_LINK_INFO:
pinos_log_warn ("got unexpected message %d", type); pinos_log_warn ("got unexpected message %d", type);
break; break;

View file

@ -26,21 +26,21 @@
extern "C" { extern "C" {
#endif #endif
typedef enum { #define PINOS_CORE_URI "http://pinos.org/ns/core"
PINOS_SUBSCRIPTION_STATE_UNCONNECTED = 0, #define PINOS_CORE_PREFIX PINOS_CORE_URI "#"
PINOS_SUBSCRIPTION_STATE_CONNECTING = 1, #define PINOS_CORE_REGISTRY PINOS_CORE_PREFIX "Registry"
PINOS_SUBSCRIPTION_STATE_READY = 2,
PINOS_SUBSCRIPTION_STATE_ERROR = 3,
} PinosSubscriptionState;
typedef enum { #define PINOS_NODE_URI "http://pinos.org/ns/node"
PINOS_SUBSCRIPTION_FLAG_DAEMON = (1 << 0), #define PINOS_NODE_PREFIX PINOS_NODE_URI "#"
PINOS_SUBSCRIPTION_FLAG_CLIENT = (1 << 1),
PINOS_SUBSCRIPTION_FLAG_NODE = (1 << 2),
PINOS_SUBSCRIPTION_FLAG_LINK = (1 << 3)
} PinosSubscriptionFlags;
#define PINOS_SUBSCRIPTION_FLAGS_ALL 0x0f #define PINOS_CLIENT_URI "http://pinos.org/ns/client"
#define PINOS_CLIENT_PREFIX PINOS_CLIENT_URI "#"
#define PINOS_LINK_URI "http://pinos.org/ns/link"
#define PINOS_LINK_PREFIX PINOS_LINK_URI "#"
#define PINOS_MODULE_URI "http://pinos.org/ns/module"
#define PINOS_MODULE_PREFIX PINOS_MODULE_URI "#"
typedef enum { typedef enum {
PINOS_SUBSCRIPTION_EVENT_NEW = 0, PINOS_SUBSCRIPTION_EVENT_NEW = 0,
@ -49,13 +49,12 @@ typedef enum {
} PinosSubscriptionEvent; } PinosSubscriptionEvent;
typedef void (*PinosSubscriptionFunc) (PinosContext *context, typedef void (*PinosSubscriptionFunc) (PinosContext *context,
PinosSubscriptionFlags flags,
PinosSubscriptionEvent event, PinosSubscriptionEvent event,
uint32_t type,
uint32_t id, uint32_t id,
void *data); void *data);
void pinos_context_subscribe (PinosContext *context, void pinos_context_subscribe (PinosContext *context,
PinosSubscriptionFlags mask,
PinosSubscriptionFunc func, PinosSubscriptionFunc func,
void *data); void *data);

View file

@ -20,8 +20,9 @@
#include <string.h> #include <string.h>
#include "pinos/client/pinos.h" #include "pinos/client/pinos.h"
#include "pinos/client/uri.h"
#include "pinos/server/core.h" #include "pinos/server/core.h"
#include "pinos/server/uri.h"
#include "pinos/server/node.h" #include "pinos/server/node.h"
#include "pinos/server/node-factory.h" #include "pinos/server/node-factory.h"
#include "pinos/server/client.h" #include "pinos/server/client.h"
@ -47,5 +48,4 @@ pinos_uri_init (PinosURI *uri)
uri->spa_node = spa_id_map_get_id (uri->map, SPA_NODE_URI); uri->spa_node = spa_id_map_get_id (uri->map, SPA_NODE_URI);
uri->spa_clock = spa_id_map_get_id (uri->map, SPA_CLOCK_URI); uri->spa_clock = spa_id_map_get_id (uri->map, SPA_CLOCK_URI);
uri->spa_monitor = spa_id_map_get_id (uri->map, SPA_MONITOR_URI); uri->spa_monitor = spa_id_map_get_id (uri->map, SPA_MONITOR_URI);
} }

View file

@ -1,5 +1,5 @@
#load-module libpinos-module-protocol-dbus #load-module libpinos-module-protocol-dbus
load-module libpinos-module-protocol-native load-module libpinos-module-protocol-native
load-module libpinos-module-suspend-on-idle load-module libpinos-module-suspend-on-idle
load-module libpinos-module-spa load-module libpinos-module-spa --pattern snow
load-module libpinos-module-autolink load-module libpinos-module-autolink

View file

@ -190,8 +190,8 @@ new_node (const PinosNodeInfo *info)
{ {
GstCaps *caps; GstCaps *caps;
GstStructure *props; GstStructure *props;
gpointer state = NULL;
const gchar *klass; const gchar *klass;
SpaDictItem *item;
/* FIXME, iterate ports */ /* FIXME, iterate ports */
#if 0 #if 0
@ -202,18 +202,10 @@ new_node (const PinosNodeInfo *info)
caps = gst_caps_new_any(); caps = gst_caps_new_any();
props = gst_structure_new_empty ("pinos-proplist"); props = gst_structure_new_empty ("pinos-proplist");
spa_dict_for_each (item, info->props)
gst_structure_set (props, item->key, G_TYPE_STRING, item->value, NULL);
while (TRUE) { klass = spa_dict_lookup (info->props, "gstreamer.device.class");
const char *key, *val;
if (!(key = pinos_properties_iterate (info->properties, &state)))
break;
val = pinos_properties_get (info->properties, key);
gst_structure_set (props, key, G_TYPE_STRING, val, NULL);
}
klass = pinos_properties_get (info->properties, "gstreamer.device.class");
if (klass == NULL) if (klass == NULL)
klass = "unknown/unknown"; klass = "unknown/unknown";
@ -263,8 +255,8 @@ find_device (GstDeviceProvider *provider, uint32_t id)
static void static void
context_subscribe_cb (PinosContext *context, context_subscribe_cb (PinosContext *context,
PinosSubscriptionFlags flags, PinosSubscriptionEvent event,
PinosSubscriptionEvent type, uint32_t type,
uint32_t id, uint32_t id,
void *user_data) void *user_data)
{ {
@ -272,19 +264,19 @@ context_subscribe_cb (PinosContext *context,
GstDeviceProvider *provider = user_data; GstDeviceProvider *provider = user_data;
GstPinosDevice *dev; GstPinosDevice *dev;
if (flags != PINOS_SUBSCRIPTION_FLAG_NODE) if (type != context->uri.node)
return; return;
dev = find_device (provider, id); dev = find_device (provider, id);
if (type == PINOS_SUBSCRIPTION_EVENT_NEW) { if (event == PINOS_SUBSCRIPTION_EVENT_NEW) {
if (flags == PINOS_SUBSCRIPTION_FLAG_NODE && dev == NULL) if (dev == NULL)
pinos_context_get_node_info_by_id (context, pinos_context_get_node_info_by_id (context,
id, id,
get_node_info_cb, get_node_info_cb,
self); self);
} else if (type == PINOS_SUBSCRIPTION_EVENT_REMOVE) { } else if (event == PINOS_SUBSCRIPTION_EVENT_REMOVE) {
if (flags == PINOS_SUBSCRIPTION_FLAG_NODE && dev != NULL) { if (dev != NULL) {
gst_device_provider_device_remove (GST_DEVICE_PROVIDER (self), gst_device_provider_device_remove (GST_DEVICE_PROVIDER (self),
GST_DEVICE (dev)); GST_DEVICE (dev));
} }
@ -313,15 +305,15 @@ list_node_info_cb (PinosContext *c,
} }
static void static void
get_daemon_info_cb (PinosContext *c, get_core_info_cb (PinosContext *c,
SpaResult res, SpaResult res,
const PinosDaemonInfo *info, const PinosCoreInfo *info,
void *user_data) void *user_data)
{ {
GstDeviceProvider *provider = user_data; GstDeviceProvider *provider = user_data;
const gchar *value; const gchar *value;
value = pinos_properties_get (info->properties, "gstreamer.deviceproviders"); value = spa_dict_lookup (info->props, "gstreamer.deviceproviders");
if (value) { if (value) {
gchar **providers = g_strsplit (value, ",", -1); gchar **providers = g_strsplit (value, ",", -1);
gint i; gint i;
@ -371,9 +363,9 @@ gst_pinos_device_provider_probe (GstDeviceProvider * provider)
} }
GST_DEBUG_OBJECT (self, "connected"); GST_DEBUG_OBJECT (self, "connected");
pinos_context_get_daemon_info (c, pinos_context_get_core_info (c,
get_daemon_info_cb, get_core_info_cb,
self); self);
data.end = FALSE; data.end = FALSE;
@ -453,7 +445,6 @@ gst_pinos_device_provider_start (GstDeviceProvider * provider)
pinos_signal_add (&self->context->state_changed, &self->ctx_state_changed, on_context_state_changed); pinos_signal_add (&self->context->state_changed, &self->ctx_state_changed, on_context_state_changed);
pinos_context_subscribe (self->context, pinos_context_subscribe (self->context,
PINOS_SUBSCRIPTION_FLAGS_ALL,
context_subscribe_cb, context_subscribe_cb,
self); self);
@ -475,9 +466,9 @@ gst_pinos_device_provider_start (GstDeviceProvider * provider)
pinos_thread_main_loop_wait (self->main_loop); pinos_thread_main_loop_wait (self->main_loop);
} }
GST_DEBUG_OBJECT (self, "connected"); GST_DEBUG_OBJECT (self, "connected");
pinos_context_get_daemon_info (self->context, pinos_context_get_core_info (self->context,
get_daemon_info_cb, get_core_info_cb,
self); self);
pinos_thread_main_loop_unlock (self->main_loop); pinos_thread_main_loop_unlock (self->main_loop);
return TRUE; return TRUE;

View file

@ -29,14 +29,12 @@
typedef struct { typedef struct {
PinosCore *core; PinosCore *core;
PinosProperties *properties; PinosProperties *properties;
PinosGlobal *global;
PinosListener global_added; PinosListener global_added;
PinosListener global_removed; PinosListener global_removed;
PinosListener port_added; PinosListener port_added;
PinosListener port_removed; PinosListener port_removed;
PinosListener port_unlinked; PinosListener port_unlinked;
PinosListener node_state_changed;
PinosListener link_state_changed; PinosListener link_state_changed;
} ModuleImpl; } ModuleImpl;
@ -184,22 +182,6 @@ on_node_created (PinosNode *node,
on_port_added (&impl->port_added, node, port); on_port_added (&impl->port_added, node, port);
} }
static void
on_node_state_changed (PinosListener *listener,
PinosNode *node,
PinosNodeState old,
PinosNodeState state)
{
ModuleImpl *impl = SPA_CONTAINER_OF (listener, ModuleImpl, node_state_changed);
pinos_log_debug ("module %p: node %p state change %s -> %s", impl, node,
pinos_node_state_as_string (old),
pinos_node_state_as_string (state));
if (old == PINOS_NODE_STATE_CREATING && state == PINOS_NODE_STATE_SUSPENDED)
on_node_created (node, impl);
}
static void static void
on_node_added (ModuleImpl *impl, PinosNode *node) on_node_added (ModuleImpl *impl, PinosNode *node)
{ {
@ -264,15 +246,11 @@ module_new (PinosCore *core,
pinos_signal_add (&core->global_added, &impl->global_added, on_global_added); pinos_signal_add (&core->global_added, &impl->global_added, on_global_added);
pinos_signal_add (&core->global_removed, &impl->global_removed, on_global_removed); pinos_signal_add (&core->global_removed, &impl->global_removed, on_global_removed);
pinos_signal_add (&core->node_state_changed, &impl->node_state_changed, on_node_state_changed);
pinos_signal_add (&core->port_added, &impl->port_added, on_port_added); pinos_signal_add (&core->port_added, &impl->port_added, on_port_added);
pinos_signal_add (&core->port_removed, &impl->port_removed, on_port_removed); pinos_signal_add (&core->port_removed, &impl->port_removed, on_port_removed);
pinos_signal_add (&core->port_unlinked, &impl->port_unlinked, on_link_port_unlinked); pinos_signal_add (&core->port_unlinked, &impl->port_unlinked, on_link_port_unlinked);
pinos_signal_add (&core->link_state_changed, &impl->link_state_changed, on_link_state_changed); pinos_signal_add (&core->link_state_changed, &impl->link_state_changed, on_link_state_changed);
impl->global = pinos_core_add_global (core,
core->uri.module,
impl);
return impl; return impl;
} }
@ -286,7 +264,6 @@ module_destroy (ModuleImpl *impl)
pinos_signal_remove (&impl->global_added); pinos_signal_remove (&impl->global_added);
pinos_signal_remove (&impl->global_removed); pinos_signal_remove (&impl->global_removed);
pinos_signal_remove (&impl->node_state_changed);
pinos_signal_remove (&impl->port_added); pinos_signal_remove (&impl->port_added);
pinos_signal_remove (&impl->port_removed); pinos_signal_remove (&impl->port_removed);
pinos_signal_remove (&impl->port_unlinked); pinos_signal_remove (&impl->port_unlinked);

View file

@ -53,7 +53,6 @@
typedef struct { typedef struct {
PinosCore *core; PinosCore *core;
SpaList link; SpaList link;
PinosGlobal *global;
PinosProperties *properties; PinosProperties *properties;
@ -164,6 +163,7 @@ find_object (PinosProtocolDBus *impl,
return NULL; return NULL;
} }
#if 0
struct _PinosProperties { struct _PinosProperties {
GHashTable *hashtable; GHashTable *hashtable;
}; };
@ -173,13 +173,14 @@ add_to_variant (const gchar *key, const gchar *value, GVariantBuilder *b)
{ {
g_variant_builder_add (b, "{sv}", key, g_variant_new_string (value)); g_variant_builder_add (b, "{sv}", key, g_variant_new_string (value));
} }
#endif
static void static void
pinos_properties_init_builder (PinosProperties *properties, pinos_properties_init_builder (PinosProperties *properties,
GVariantBuilder *builder) GVariantBuilder *builder)
{ {
g_variant_builder_init (builder, G_VARIANT_TYPE ("a{sv}")); g_variant_builder_init (builder, G_VARIANT_TYPE ("a{sv}"));
g_hash_table_foreach (properties->hashtable, (GHFunc) add_to_variant, builder); // g_hash_table_foreach (properties->hashtable, (GHFunc) add_to_variant, builder);
} }
static GVariant * static GVariant *
@ -201,10 +202,10 @@ pinos_properties_from_variant (GVariant *variant)
props = pinos_properties_new (NULL, NULL); props = pinos_properties_new (NULL, NULL);
g_variant_iter_init (&iter, variant); g_variant_iter_init (&iter, variant);
while (g_variant_iter_loop (&iter, "{sv}", &key, &value)) // while (g_variant_iter_loop (&iter, "{sv}", &key, &value))
g_hash_table_replace (props->hashtable, //g_hash_table_replace (props->hashtable,
g_strdup (key), // g_strdup (key),
g_variant_dup_string (value, NULL)); // g_variant_dup_string (value, NULL));
return props; return props;
} }
@ -684,9 +685,6 @@ pinos_protocol_dbus_new (PinosCore *core,
impl->server_manager = g_dbus_object_manager_server_new (PINOS_DBUS_OBJECT_PREFIX); impl->server_manager = g_dbus_object_manager_server_new (PINOS_DBUS_OBJECT_PREFIX);
impl->global = pinos_core_add_global (core,
core->uri.module,
impl);
return impl; return impl;
} }

View file

@ -64,220 +64,33 @@ typedef struct {
typedef struct { typedef struct {
PinosCore *core; PinosCore *core;
SpaList link; SpaList link;
PinosGlobal *global;
PinosProperties *properties; PinosProperties *properties;
SpaList socket_list; SpaList socket_list;
SpaList client_list; SpaList client_list;
SpaList object_list;
PinosListener global_added;
PinosListener global_removed;
PinosListener node_state_changed;
} PinosProtocolNative; } PinosProtocolNative;
typedef struct { typedef struct {
PinosProtocolNative *impl; PinosProtocolNative *impl;
SpaList link; SpaList link;
PinosGlobal *global; PinosClient *client;
PinosDestroy destroy; int fd;
} PinosProtocolNativeObject; struct ucred ucred;
SpaSource *source;
typedef struct { PinosConnection *connection;
PinosProtocolNativeObject parent;
SpaList link;
} PinosProtocolNativeServer;
typedef struct {
PinosProtocolNativeObject parent;
SpaList link;
int fd;
struct ucred ucred;
SpaSource *source;
PinosConnection *connection;
PinosResource *core_resource;
} PinosProtocolNativeClient; } PinosProtocolNativeClient;
typedef struct {
PinosProtocolNativeObject parent;
PinosListener state_changed;
} PinosProtocolNativeNode;
static void *
object_new (size_t size,
PinosProtocolNative *impl,
PinosGlobal *global,
PinosDestroy destroy)
{
PinosProtocolNativeObject *this;
this = calloc (1, size);
this->impl = impl;
this->global = global;
this->destroy = destroy;
spa_list_insert (impl->object_list.prev, &this->link);
return this;
}
static void
sync_destroy (void *object,
void *data,
SpaResult res,
uint32_t id)
{
PinosProtocolNativeObject *this = object;
if (this->destroy)
this->destroy (this);
free (this);
}
static void
object_destroy (PinosProtocolNativeObject *this)
{
spa_list_remove (&this->link);
pinos_main_loop_defer (this->impl->core->main_loop,
this,
SPA_RESULT_WAIT_SYNC,
sync_destroy,
this);
}
static PinosProtocolNativeObject *
find_object (PinosProtocolNative *impl,
void *object)
{
PinosProtocolNativeObject *obj;
spa_list_for_each (obj, &impl->object_list, link) {
if (obj->global->object == object)
return obj;
}
return NULL;
}
static void static void
client_destroy (PinosProtocolNativeClient *this) client_destroy (PinosProtocolNativeClient *this)
{ {
pinos_client_destroy (this->client);
spa_list_remove (&this->link); spa_list_remove (&this->link);
if (this->source) pinos_loop_destroy_source (this->impl->core->main_loop->loop,
pinos_loop_destroy_source (this->parent.impl->core->main_loop->loop, this->source);
this->source);
pinos_connection_destroy (this->connection); pinos_connection_destroy (this->connection);
close (this->fd); close (this->fd);
} free (this);
static void
destroy_registry_resource (void *object)
{
PinosResource *resource = object;
spa_list_remove (&resource->link);
}
static SpaResult
registry_dispatch_func (void *object,
PinosMessageType type,
void *message,
void *data)
{
switch (type) {
case PINOS_MESSAGE_BIND:
break;
default:
pinos_log_error ("unhandled message %d", type);
break;
}
return SPA_RESULT_OK;
}
static SpaResult
core_dispatch_func (void *object,
PinosMessageType type,
void *message,
void *data)
{
PinosProtocolNativeClient *client = data;
PinosProtocolNative *impl = client->parent.impl;
PinosClient *c = client->parent.global->object;
switch (type) {
case PINOS_MESSAGE_GET_REGISTRY:
{
PinosMessageGetRegistry *m = message;
PinosGlobal *global;
PinosMessageNotifyDone nd;
PinosResource *registry_resource;
registry_resource = pinos_resource_new (c,
SPA_ID_INVALID,
impl->core->uri.registry,
impl->core,
destroy_registry_resource);
registry_resource->dispatch_func = registry_dispatch_func;
registry_resource->dispatch_data = client;
spa_list_insert (impl->core->registry_resource_list.prev, &registry_resource->link);
spa_list_for_each (global, &impl->core->global_list, link) {
PinosMessageNotifyGlobal ng;
ng.id = global->id;
ng.type = spa_id_map_get_uri (impl->core->uri.map, global->type);
pinos_resource_send_message (registry_resource,
PINOS_MESSAGE_NOTIFY_GLOBAL,
&ng,
false);
}
nd.seq = m->seq;
pinos_resource_send_message (client->core_resource,
PINOS_MESSAGE_NOTIFY_DONE,
&nd,
true);
break;
}
case PINOS_MESSAGE_CREATE_CLIENT_NODE:
{
PinosMessageCreateClientNode *m = message;
PinosClientNode *node;
SpaResult res;
int data_fd, i;
PinosMessageCreateClientNodeDone r;
PinosProperties *props;
props = pinos_properties_new (NULL, NULL);
for (i = 0; i < m->props->n_items; i++) {
pinos_properties_set (props, m->props->items[i].key,
m->props->items[i].value);
}
node = pinos_client_node_new (c,
m->new_id,
m->name,
props);
if ((res = pinos_client_node_get_data_socket (node, &data_fd)) < 0) {
pinos_log_error ("can't get data fd");
break;
}
r.seq = m->seq;
r.datafd = data_fd;
pinos_resource_send_message (node->resource,
PINOS_MESSAGE_CREATE_CLIENT_NODE_DONE,
&r,
true);
break;
}
default:
pinos_log_error ("unhandled message %d", type);
break;
}
return SPA_RESULT_OK;
} }
static SpaResult static SpaResult
@ -290,7 +103,8 @@ client_send_func (void *object,
{ {
PinosProtocolNativeClient *client = data; PinosProtocolNativeClient *client = data;
pinos_log_debug ("protocol-native %p: sending message %d to %u", client->parent.impl, type, id); pinos_log_debug ("protocol-native %p: sending message %d to %u of client %p",
client->impl, type, id, client);
pinos_connection_add_message (client->connection, pinos_connection_add_message (client->connection,
id, id,
@ -313,14 +127,11 @@ connection_data (SpaSource *source,
PinosMessageType type; PinosMessageType type;
uint32_t id; uint32_t id;
size_t size; size_t size;
PinosClient *c = client->parent.global->object; PinosClient *c = client->client;
if (mask & (SPA_IO_ERR | SPA_IO_HUP)) { if (mask & (SPA_IO_ERR | SPA_IO_HUP)) {
pinos_log_debug ("protocol-native %p: got connection error", client->parent.impl); pinos_log_debug ("protocol-native %p: got connection error", client->impl);
pinos_loop_destroy_source (client->parent.impl->core->main_loop->loop, client_destroy (client);
client->source);
client->source = NULL;
pinos_client_destroy (client->parent.global->object);
return; return;
} }
@ -328,16 +139,16 @@ connection_data (SpaSource *source,
PinosResource *resource; PinosResource *resource;
void *message = alloca (size); void *message = alloca (size);
pinos_log_debug ("protocol-native %p: got message %d from %u", client->parent.impl, type, id); pinos_log_debug ("protocol-native %p: got message %d from %u", client->impl, type, id);
if (!pinos_connection_parse_message (conn, message)) { if (!pinos_connection_parse_message (conn, message)) {
pinos_log_error ("protocol-native %p: failed to parse message", client->parent.impl); pinos_log_error ("protocol-native %p: failed to parse message", client->impl);
continue; continue;
} }
resource = pinos_map_lookup (&c->objects, id); resource = pinos_map_lookup (&c->objects, id);
if (resource == NULL) { if (resource == NULL) {
pinos_log_error ("protocol-native %p: unknown resource %u", client->parent.impl, id); pinos_log_error ("protocol-native %p: unknown resource %u", client->impl, id);
continue; continue;
} }
@ -353,27 +164,14 @@ client_new (PinosProtocolNative *impl,
int fd) int fd)
{ {
PinosProtocolNativeClient *this; PinosProtocolNativeClient *this;
PinosClient *client;
socklen_t len; socklen_t len;
client = pinos_client_new (impl->core, NULL); this = calloc (1, sizeof (PinosProtocolNativeClient));
this->impl = impl;
if ((this = (PinosProtocolNativeClient *) find_object (impl, client)) == NULL) { len = sizeof (this->ucred);
close (fd); if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &this->ucred, &len) < 0) {
return NULL; pinos_log_error ("no peercred: %m");
} }
client->send_func = client_send_func;
client->send_data = this;
this->core_resource = pinos_resource_new (client,
0,
impl->core->uri.core,
impl->core,
NULL);
this->core_resource->dispatch_func = core_dispatch_func;
this->core_resource->dispatch_data = this;
this->fd = fd; this->fd = fd;
this->source = pinos_loop_add_io (impl->core->main_loop->loop, this->source = pinos_loop_add_io (impl->core->main_loop->loop,
this->fd, this->fd,
@ -381,75 +179,23 @@ client_new (PinosProtocolNative *impl,
false, false,
connection_data, connection_data,
this); this);
len = sizeof (this->ucred);
if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &this->ucred, &len) < 0) {
pinos_log_error ("no peercred: %m");
}
this->connection = pinos_connection_new (fd); this->connection = pinos_connection_new (fd);
spa_list_insert (impl->client_list.prev, &this->link); spa_list_insert (impl->client_list.prev, &this->link);
this->client = pinos_client_new (impl->core, NULL);
this->client->send_func = client_send_func;
this->client->send_data = this;
impl->core->global->bind (impl->core->global,
this->client,
0,
0);
return this; return this;
} }
static void
on_global_added (PinosListener *listener,
PinosCore *core,
PinosGlobal *global)
{
PinosProtocolNative *impl = SPA_CONTAINER_OF (listener, PinosProtocolNative, global_added);
PinosMessageNotifyGlobal ng;
PinosResource *registry;
if (global->type == impl->core->uri.client) {
object_new (sizeof (PinosProtocolNativeClient),
impl,
global,
(PinosDestroy) client_destroy);
} else if (global->type == impl->core->uri.node) {
object_new (sizeof (PinosProtocolNativeNode),
impl,
global,
NULL);
} else if (global->type == impl->core->uri.link) {
}
ng.id = global->id;
ng.type = spa_id_map_get_uri (impl->core->uri.map, global->type);
spa_list_for_each (registry, &core->registry_resource_list, link) {
pinos_resource_send_message (registry,
PINOS_MESSAGE_NOTIFY_GLOBAL,
&ng,
true);
}
}
static void
on_global_removed (PinosListener *listener,
PinosCore *core,
PinosGlobal *global)
{
PinosProtocolNative *impl = SPA_CONTAINER_OF (listener, PinosProtocolNative, global_removed);
PinosProtocolNativeObject *object;
PinosMessageNotifyGlobalRemove ng;
PinosResource *registry;
if ((object = find_object (impl, global->object))) {
object_destroy (object);
}
ng.id = global->id;
spa_list_for_each (registry, &core->registry_resource_list, link) {
pinos_resource_send_message (registry,
PINOS_MESSAGE_NOTIFY_GLOBAL_REMOVE,
&ng,
true);
}
}
static Socket * static Socket *
create_socket (void) create_socket (void)
{ {
@ -628,7 +374,6 @@ pinos_protocol_native_new (PinosCore *core,
spa_list_init (&impl->socket_list); spa_list_init (&impl->socket_list);
spa_list_init (&impl->client_list); spa_list_init (&impl->client_list);
spa_list_init (&impl->object_list);
if (!init_socket_name (s, name)) if (!init_socket_name (s, name))
goto error; goto error;
@ -639,12 +384,6 @@ pinos_protocol_native_new (PinosCore *core,
if (!add_socket (impl, s)) if (!add_socket (impl, s))
goto error; goto error;
pinos_signal_add (&core->global_added, &impl->global_added, on_global_added);
pinos_signal_add (&core->global_removed, &impl->global_removed, on_global_removed);
impl->global = pinos_core_add_global (core,
core->uri.module,
impl);
return impl; return impl;
error: error:
@ -666,10 +405,6 @@ pinos_protocol_native_destroy (PinosProtocolNative *impl)
spa_list_for_each_safe (object, tmp, &impl->object_list, link) spa_list_for_each_safe (object, tmp, &impl->object_list, link)
object_destroy (object); object_destroy (object);
pinos_signal_remove (&impl->global_added);
pinos_signal_remove (&impl->global_removed);
pinos_signal_remove (&impl->node_state_changed);
free (impl); free (impl);
} }
#endif #endif

View file

@ -29,7 +29,6 @@
typedef struct { typedef struct {
PinosCore *core; PinosCore *core;
PinosProperties *properties; PinosProperties *properties;
PinosGlobal *global;
PinosListener global_added; PinosListener global_added;
PinosListener global_removed; PinosListener global_removed;
@ -189,9 +188,6 @@ module_new (PinosCore *core,
pinos_signal_add (&core->node_state_request, &impl->node_state_request, on_node_state_request); pinos_signal_add (&core->node_state_request, &impl->node_state_request, on_node_state_request);
pinos_signal_add (&core->node_state_changed, &impl->node_state_changed, on_node_state_changed); pinos_signal_add (&core->node_state_changed, &impl->node_state_changed, on_node_state_changed);
impl->global = pinos_core_add_global (core,
core->uri.module,
impl);
return impl; return impl;
} }

View file

@ -21,6 +21,8 @@
#include <getopt.h> #include <getopt.h>
#include <limits.h> #include <limits.h>
#include <spa/lib/props.h>
#include <pinos/client/utils.h> #include <pinos/client/utils.h>
#include <pinos/server/core.h> #include <pinos/server/core.h>
#include <pinos/server/module.h> #include <pinos/server/module.h>
@ -28,6 +30,43 @@
#include "spa-monitor.h" #include "spa-monitor.h"
#include "spa-node.h" #include "spa-node.h"
static SpaResult
setup_video_node (SpaNode *spa_node, PinosProperties *pinos_props) {
SpaResult res;
SpaProps *props;
SpaPropValue value;
const char *pattern;
uint32_t pattern_int;
/* Retrieve pattern property */
pattern = pinos_properties_get (pinos_props, "pattern");
if (strcmp (pattern, "smpte-snow") == 0) {
pattern_int = 0;
} else if (strcmp (pattern, "snow") == 0) {
pattern_int = 1;
} else {
pinos_log_debug ("Unrecognized pattern");
return SPA_RESULT_ERROR;
}
value.value = &pattern_int;
value.size = sizeof(uint32_t);
if ((res = spa_node_get_props (spa_node, &props)) != SPA_RESULT_OK) {
pinos_log_debug ("spa_node_get_props failed: %d", res);
return SPA_RESULT_ERROR;
}
spa_props_set_value (props, spa_props_index_for_name (props, "pattern"), &value);
if ((res = spa_node_set_props (spa_node, props)) != SPA_RESULT_OK) {
pinos_log_debug ("spa_node_set_props failed: %d", res);
return SPA_RESULT_ERROR;
}
return SPA_RESULT_OK;
}
bool bool
pinos__module_init (PinosModule * module, const char * args) pinos__module_init (PinosModule * module, const char * args)
{ {
@ -82,12 +121,14 @@ pinos__module_init (PinosModule * module, const char * args)
"build/spa/plugins/audiotestsrc/libspa-audiotestsrc.so", "build/spa/plugins/audiotestsrc/libspa-audiotestsrc.so",
"audiotestsrc", "audiotestsrc",
"audiotestsrc", "audiotestsrc",
NULL,
NULL); NULL);
pinos_spa_node_load (module->core, pinos_spa_node_load (module->core,
"build/spa/plugins/videotestsrc/libspa-videotestsrc.so", "build/spa/plugins/videotestsrc/libspa-videotestsrc.so",
"videotestsrc", "videotestsrc",
"videotestsrc", "videotestsrc",
video_props); video_props,
setup_video_node);
return true; return true;
} }

View file

@ -37,7 +37,8 @@ pinos_spa_node_load (PinosCore *core,
const char *lib, const char *lib,
const char *factory_name, const char *factory_name,
const char *name, const char *name,
PinosProperties *properties) PinosProperties *properties,
SetupNode setup_func)
{ {
PinosSpaNode *this; PinosSpaNode *this;
PinosSpaNodeImpl *impl; PinosSpaNodeImpl *impl;
@ -97,6 +98,13 @@ pinos_spa_node_load (PinosCore *core,
impl->core = core; impl->core = core;
impl->hnd = hnd; impl->hnd = hnd;
this = &impl->this; this = &impl->this;
if (setup_func != NULL) {
if (setup_func (spa_node, properties) != SPA_RESULT_OK) {
pinos_log_debug ("Unrecognized properties");
}
}
this->node = pinos_node_new (core, this->node = pinos_node_new (core,
name, name,
spa_node, spa_node,

View file

@ -26,6 +26,7 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
typedef struct _PinosSpaNode PinosSpaNode; typedef struct _PinosSpaNode PinosSpaNode;
struct _PinosSpaNode { struct _PinosSpaNode {
@ -38,11 +39,15 @@ struct _PinosSpaNode {
PinosSpaNode *node)); PinosSpaNode *node));
}; };
typedef SpaResult (*SetupNode) (SpaNode *spa_node,
PinosProperties *pinos_props);
PinosSpaNode * pinos_spa_node_load (PinosCore *core, PinosSpaNode * pinos_spa_node_load (PinosCore *core,
const char *lib, const char *lib,
const char *factory_name, const char *factory_name,
const char *name, const char *name,
PinosProperties *properties); PinosProperties *properties,
SetupNode setup_func);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -28,6 +28,57 @@ typedef struct
PinosClient this; PinosClient this;
} PinosClientImpl; } PinosClientImpl;
static SpaResult
client_dispatch_func (void *object,
PinosMessageType type,
void *message,
void *data)
{
PinosResource *resource = object;
PinosClient *client = resource->object;
switch (type) {
default:
pinos_log_warn ("client %p: unhandled message %d", client, type);
break;
}
return SPA_RESULT_OK;
}
static void
client_bind_func (PinosGlobal *global,
PinosClient *client,
uint32_t version,
uint32_t id)
{
PinosClient *this = global->object;
PinosResource *resource;
PinosMessageClientInfo m;
PinosClientInfo info;
resource = pinos_resource_new (client,
id,
global->core->uri.client,
global->object,
NULL);
resource->dispatch_func = client_dispatch_func;
resource->dispatch_data = global;
pinos_log_debug ("client %p: bound to %d", global->object, resource->id);
m.info = &info;
info.id = resource->id;
info.change_mask = ~0;
info.props = this->properties ? &this->properties->dict : NULL;
pinos_resource_send_message (resource,
PINOS_MESSAGE_CLIENT_INFO,
&m,
true);
}
/** /**
* pinos_client_new: * pinos_client_new:
* @daemon: a #PinosDaemon * @daemon: a #PinosDaemon
@ -58,7 +109,9 @@ pinos_client_new (PinosCore *core,
this->global = pinos_core_add_global (core, this->global = pinos_core_add_global (core,
core->uri.client, core->uri.client,
this); 0,
this,
client_bind_func);
return this; return this;
} }

View file

@ -24,9 +24,6 @@
extern "C" { extern "C" {
#endif #endif
#define PINOS_CLIENT_URI "http://pinos.org/ns/client"
#define PINOS_CLIENT_PREFIX PINOS_CLIENT_URI "#"
typedef struct _PinosClient PinosClient; typedef struct _PinosClient PinosClient;
#include <pinos/server/core.h> #include <pinos/server/core.h>
@ -44,6 +41,8 @@ struct _PinosClient {
PinosProperties *properties; PinosProperties *properties;
PinosResource *core_resource;
PinosMap objects; PinosMap objects;
PinosSendFunc send_func; PinosSendFunc send_func;

View file

@ -20,6 +20,7 @@
#include <pinos/client/pinos.h> #include <pinos/client/pinos.h>
#include <pinos/server/core.h> #include <pinos/server/core.h>
#include <pinos/server/data-loop.h> #include <pinos/server/data-loop.h>
#include <pinos/server/client-node.h>
typedef struct { typedef struct {
PinosCore this; PinosCore this;
@ -28,6 +29,179 @@ typedef struct {
} PinosCoreImpl; } PinosCoreImpl;
static SpaResult
registry_dispatch_func (void *object,
PinosMessageType type,
void *message,
void *data)
{
PinosResource *resource = object;
PinosClient *client = resource->client;
PinosCore *this = data;
switch (type) {
case PINOS_MESSAGE_BIND:
{
PinosMessageBind *m = message;
PinosGlobal *global;
spa_list_for_each (global, &this->global_list, link)
if (global->id == m->id)
break;
if (&global->link == &this->global_list) {
pinos_log_error ("unknown object id %d", m->id);
return SPA_RESULT_ERROR;
}
if (global->bind == NULL) {
pinos_log_error ("can't bind object id %d", m->id);
return SPA_RESULT_ERROR;
}
pinos_log_error ("global %p: bind object id %d", global, m->id);
global->bind (global, client, 0, m->id);
break;
}
default:
pinos_log_error ("unhandled message %d", type);
break;
}
return SPA_RESULT_OK;
}
static void
destroy_registry_resource (void *object)
{
PinosResource *resource = object;
spa_list_remove (&resource->link);
}
static SpaResult
core_dispatch_func (void *object,
PinosMessageType type,
void *message,
void *data)
{
PinosResource *resource = object;
PinosClient *client = resource->client;
PinosCore *this = data;
switch (type) {
case PINOS_MESSAGE_GET_REGISTRY:
{
PinosMessageGetRegistry *m = message;
PinosGlobal *global;
PinosMessageNotifyDone nd;
PinosResource *registry_resource;
registry_resource = pinos_resource_new (resource->client,
SPA_ID_INVALID,
this->uri.registry,
this,
destroy_registry_resource);
registry_resource->dispatch_func = registry_dispatch_func;
registry_resource->dispatch_data = this;
spa_list_insert (this->registry_resource_list.prev, &registry_resource->link);
spa_list_for_each (global, &this->global_list, link) {
PinosMessageNotifyGlobal ng;
ng.id = global->id;
ng.type = spa_id_map_get_uri (this->uri.map, global->type);
pinos_resource_send_message (registry_resource,
PINOS_MESSAGE_NOTIFY_GLOBAL,
&ng,
false);
}
nd.seq = m->seq;
pinos_resource_send_message (client->core_resource,
PINOS_MESSAGE_NOTIFY_DONE,
&nd,
true);
break;
}
case PINOS_MESSAGE_CREATE_CLIENT_NODE:
{
PinosMessageCreateClientNode *m = message;
PinosClientNode *node;
SpaResult res;
int data_fd, i;
PinosMessageCreateClientNodeDone r;
PinosProperties *props;
props = pinos_properties_new (NULL, NULL);
for (i = 0; i < m->props->n_items; i++) {
pinos_properties_set (props, m->props->items[i].key,
m->props->items[i].value);
}
node = pinos_client_node_new (client,
m->new_id,
m->name,
props);
if ((res = pinos_client_node_get_data_socket (node, &data_fd)) < 0) {
pinos_log_error ("can't get data fd");
break;
}
r.seq = m->seq;
r.datafd = data_fd;
pinos_resource_send_message (node->resource,
PINOS_MESSAGE_CREATE_CLIENT_NODE_DONE,
&r,
true);
break;
}
default:
pinos_log_error ("unhandled message %d", type);
break;
}
return SPA_RESULT_OK;
}
static void
core_bind_func (PinosGlobal *global,
PinosClient *client,
uint32_t version,
uint32_t id)
{
PinosCore *this = global->object;
PinosResource *resource;
PinosMessageCoreInfo m;
PinosCoreInfo info;
resource = pinos_resource_new (client,
id,
global->core->uri.core,
global->object,
NULL);
resource->dispatch_func = core_dispatch_func;
resource->dispatch_data = this;
client->core_resource = resource;
pinos_log_debug ("core %p: bound to %d", global->object, resource->id);
m.info = &info;
info.id = resource->id;
info.change_mask = ~0;
info.user_name = "wim";
info.host_name = "wtay";
info.version = 0;
info.name = "pinos-0";
info.cookie = 0;
info.props = NULL;
pinos_resource_send_message (resource,
PINOS_MESSAGE_CORE_INFO,
&m,
true);
}
PinosCore * PinosCore *
pinos_core_new (PinosMainLoop *main_loop) pinos_core_new (PinosMainLoop *main_loop)
{ {
@ -76,7 +250,9 @@ pinos_core_new (PinosMainLoop *main_loop)
this->global = pinos_core_add_global (this, this->global = pinos_core_add_global (this,
this->uri.core, this->uri.core,
this); 0,
this,
core_bind_func);
return this; return this;
} }
@ -96,14 +272,18 @@ pinos_core_destroy (PinosCore *core)
PinosGlobal * PinosGlobal *
pinos_core_add_global (PinosCore *core, pinos_core_add_global (PinosCore *core,
uint32_t type, uint32_t type,
void *object) uint32_t version,
void *object,
PinosBindFunc bind)
{ {
PinosGlobal *global; PinosGlobal *global;
global = calloc (1, sizeof (PinosGlobal)); global = calloc (1, sizeof (PinosGlobal));
global->core = core; global->core = core;
global->type = type; global->type = type;
global->version = version;
global->object = object; global->object = object;
global->bind = bind;
pinos_signal_init (&global->destroy_signal); pinos_signal_init (&global->destroy_signal);
@ -166,6 +346,9 @@ pinos_core_find_port (PinosCore *core,
pinos_log_debug ("id \"%u\", %d", id, have_id); pinos_log_debug ("id \"%u\", %d", id, have_id);
spa_list_for_each (n, &core->node_list, link) { spa_list_for_each (n, &core->node_list, link) {
if (n->global == NULL)
continue;
pinos_log_debug ("node id \"%d\"", n->global->id); pinos_log_debug ("node id \"%d\"", n->global->id);
if (have_id) { if (have_id) {

View file

@ -27,26 +27,31 @@ extern "C" {
typedef struct _PinosCore PinosCore; typedef struct _PinosCore PinosCore;
typedef struct _PinosGlobal PinosGlobal; typedef struct _PinosGlobal PinosGlobal;
#define PINOS_CORE_URI "http://pinos.org/ns/core"
#define PINOS_CORE_PREFIX PINOS_CORE_URI "#"
#define PINOS_CORE_REGISTRY PINOS_CORE_PREFIX "Registry"
#include <spa/include/spa/log.h> #include <spa/include/spa/log.h>
#include <pinos/client/uri.h>
#include <pinos/server/main-loop.h> #include <pinos/server/main-loop.h>
#include <pinos/server/data-loop.h> #include <pinos/server/data-loop.h>
#include <pinos/server/uri.h>
#include <pinos/server/node.h> #include <pinos/server/node.h>
#include <pinos/server/link.h> #include <pinos/server/link.h>
#include <pinos/server/node-factory.h> #include <pinos/server/node-factory.h>
typedef void (*PinosBindFunc) (PinosGlobal *global,
PinosClient *client,
uint32_t version,
uint32_t id);
struct _PinosGlobal { struct _PinosGlobal {
PinosCore *core; PinosCore *core;
SpaList link; SpaList link;
uint32_t id; uint32_t id;
uint32_t type; uint32_t type;
uint32_t version;
void *object; void *object;
PinosBindFunc bind;
PINOS_SIGNAL (destroy_signal, (PinosListener *listener, PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosGlobal *global)); PinosGlobal *global));
}; };
@ -116,7 +121,9 @@ void pinos_core_destroy (PinosCore *core);
PinosGlobal * pinos_core_add_global (PinosCore *core, PinosGlobal * pinos_core_add_global (PinosCore *core,
uint32_t type, uint32_t type,
void *object); uint32_t version,
void *object,
PinosBindFunc bind);
void pinos_global_destroy (PinosGlobal *global); void pinos_global_destroy (PinosGlobal *global);

View file

@ -668,6 +668,39 @@ pinos_pinos_link_deactivate (PinosLink *this)
return true; return true;
} }
static SpaResult
link_dispatch_func (void *object,
PinosMessageType type,
void *message,
void *data)
{
switch (type) {
default:
break;
}
return SPA_RESULT_OK;
}
static void
link_bind_func (PinosGlobal *global,
PinosClient *client,
uint32_t version,
uint32_t id)
{
PinosResource *resource;
resource = pinos_resource_new (client,
id,
global->core->uri.link,
global->object,
NULL);
resource->dispatch_func = link_dispatch_func;
resource->dispatch_data = client;
pinos_log_debug ("link %p: bound to %d", global->object, resource->id);
}
PinosLink * PinosLink *
pinos_link_new (PinosCore *core, pinos_link_new (PinosCore *core,
PinosPort *output, PinosPort *output,
@ -717,7 +750,9 @@ pinos_link_new (PinosCore *core,
this->global = pinos_core_add_global (core, this->global = pinos_core_add_global (core,
core->uri.link, core->uri.link,
this); 0,
this,
link_bind_func);
return this; return this;
} }

View file

@ -26,9 +26,6 @@ extern "C" {
typedef struct _PinosLink PinosLink; typedef struct _PinosLink PinosLink;
#define PINOS_LINK_URI "http://pinos.org/ns/link"
#define PINOS_LINK_PREFIX PINOS_LINK_URI "#"
#include <spa/include/spa/ringbuffer.h> #include <spa/include/spa/ringbuffer.h>
#include <pinos/client/mem.h> #include <pinos/client/mem.h>

View file

@ -11,7 +11,6 @@ pinoscore_headers = [
'node-factory.h', 'node-factory.h',
'port.h', 'port.h',
'resource.h', 'resource.h',
'uri.h',
] ]
pinoscore_sources = [ pinoscore_sources = [
@ -27,7 +26,6 @@ pinoscore_sources = [
'node-factory.c', 'node-factory.c',
'port.c', 'port.c',
'resource.c', 'resource.c',
'uri.c',
] ]
libpinoscore_c_args = [ libpinoscore_c_args = [

View file

@ -90,6 +90,59 @@ find_module (const char * path, const char *name)
return filename; return filename;
} }
static SpaResult
module_dispatch_func (void *object,
PinosMessageType type,
void *message,
void *data)
{
PinosResource *resource = object;
PinosModule *module = resource->object;
switch (type) {
default:
pinos_log_warn ("module %p: unhandled message %d", module, type);
break;
}
return SPA_RESULT_OK;
}
static void
module_bind_func (PinosGlobal *global,
PinosClient *client,
uint32_t version,
uint32_t id)
{
PinosModule *this = global->object;
PinosResource *resource;
PinosMessageModuleInfo m;
PinosModuleInfo info;
resource = pinos_resource_new (client,
id,
global->core->uri.module,
global->object,
NULL);
resource->dispatch_func = module_dispatch_func;
resource->dispatch_data = global;
pinos_log_debug ("module %p: bound to %d", global->object, resource->id);
m.info = &info;
info.id = resource->id;
info.change_mask = ~0;
info.name = this->name;
info.filename = this->filename;
info.args = this->args;
info.props = NULL;
pinos_resource_send_message (resource,
PINOS_MESSAGE_MODULE_INFO,
&m,
true);
}
/** /**
* pinos_module_load: * pinos_module_load:
* @core: a #PinosCore * @core: a #PinosCore
@ -140,7 +193,6 @@ pinos_module_load (PinosCore *core,
pinos_log_debug ("trying to load module: %s (%s)", name, filename); pinos_log_debug ("trying to load module: %s (%s)", name, filename);
hnd = dlopen (filename, RTLD_NOW | RTLD_LOCAL); hnd = dlopen (filename, RTLD_NOW | RTLD_LOCAL);
free (filename);
if (hnd == NULL) if (hnd == NULL)
goto open_failed; goto open_failed;
@ -152,7 +204,9 @@ pinos_module_load (PinosCore *core,
impl->hnd = hnd; impl->hnd = hnd;
this = &impl->this; this = &impl->this;
this->name = strdup (name); this->name = name ? strdup (name) : NULL;
this->filename = filename;
this->args = args ? strdup (args) : NULL;
this->core = core; this->core = core;
if (!init_func (this, (char *) args)) if (!init_func (this, (char *) args))
@ -160,6 +214,12 @@ pinos_module_load (PinosCore *core,
pinos_log_debug ("loaded module: %s", this->name); pinos_log_debug ("loaded module: %s", this->name);
this->global = pinos_core_add_global (core,
core->uri.module,
0,
impl,
module_bind_func);
return this; return this;
not_found: not_found:
@ -170,12 +230,14 @@ not_found:
open_failed: open_failed:
{ {
asprintf (err, "Failed to open module: %s", dlerror ()); asprintf (err, "Failed to open module: %s", dlerror ());
free (filename);
return NULL; return NULL;
} }
no_pinos_module: no_pinos_module:
{ {
asprintf (err, "\"%s\" is not a pinos module", name); asprintf (err, "\"%s\" is not a pinos module", name);
dlclose (hnd); dlclose (hnd);
free (filename);
return NULL; return NULL;
} }
init_failed: init_failed:
@ -193,7 +255,12 @@ pinos_module_destroy (PinosModule *this)
pinos_signal_emit (&this->destroy_signal, this); pinos_signal_emit (&this->destroy_signal, this);
free (this->name); if (this->name)
free (this->name);
if (this->filename)
free (this->filename);
if (this->args)
free (this->args);
dlclose (impl->hnd); dlclose (impl->hnd);
free (impl); free (impl);
} }

View file

@ -27,16 +27,16 @@ extern "C" {
#include <pinos/server/core.h> #include <pinos/server/core.h>
#define PINOS_MODULE_URI "http://pinos.org/ns/module"
#define PINOS_MODULE_PREFIX PINOS_MODULE_URI "#"
typedef struct _PinosModule PinosModule; typedef struct _PinosModule PinosModule;
struct _PinosModule { struct _PinosModule {
PinosCore *core; PinosCore *core;
SpaList link; SpaList link;
PinosGlobal *global;
char *name; char *name;
char *filename;
char *args;
PINOS_SIGNAL (destroy_signal, (PinosListener *listener, PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosModule *module)); PinosModule *module));

View file

@ -382,6 +382,68 @@ on_node_event (SpaNode *node, SpaNodeEvent *event, void *user_data)
} }
} }
static SpaResult
node_dispatch_func (void *object,
PinosMessageType type,
void *message,
void *data)
{
PinosResource *resource = object;
PinosNode *node = resource->object;
switch (type) {
default:
pinos_log_warn ("node %p: unhandled message %d", node, type);
break;
}
return SPA_RESULT_OK;
}
static void
node_unbind_func (void *data)
{
PinosResource *resource = data;
spa_list_remove (&resource->link);
}
static void
node_bind_func (PinosGlobal *global,
PinosClient *client,
uint32_t version,
uint32_t id)
{
PinosNode *this = global->object;
PinosResource *resource;
PinosMessageNodeInfo m;
PinosNodeInfo info;
resource = pinos_resource_new (client,
id,
global->core->uri.registry,
global->object,
node_unbind_func);
resource->dispatch_func = node_dispatch_func;
resource->dispatch_data = global;
pinos_log_debug ("node %p: bound to %d", this, resource->id);
spa_list_insert (this->resource_list.prev, &resource->link);
m.info = &info;
info.id = resource->id;
info.change_mask = ~0;
info.name = this->name;
info.state = this->state;
info.props = this->properties ? &this->properties->dict : NULL;
pinos_resource_send_message (resource,
PINOS_MESSAGE_NODE_INFO,
&m,
true);
}
static void static void
init_complete (PinosNode *this) init_complete (PinosNode *this)
{ {
@ -391,7 +453,15 @@ init_complete (PinosNode *this)
pinos_log_debug ("node %p: init completed", this); pinos_log_debug ("node %p: init completed", this);
impl->async_init = false; impl->async_init = false;
spa_list_insert (this->core->node_list.prev, &this->link);
pinos_node_update_state (this, PINOS_NODE_STATE_SUSPENDED, NULL); pinos_node_update_state (this, PINOS_NODE_STATE_SUSPENDED, NULL);
this->global = pinos_core_add_global (this->core,
this->core->uri.node,
0,
this,
node_bind_func);
} }
void void
@ -424,6 +494,8 @@ pinos_node_new (PinosCore *core,
this->clock = clock; this->clock = clock;
this->data_loop = core->data_loop; this->data_loop = core->data_loop;
spa_list_init (&this->resource_list);
if (spa_node_set_event_callback (this->node, on_node_event, this) < 0) if (spa_node_set_event_callback (this->node, on_node_event, this) < 0)
pinos_log_warn ("node %p: error setting callback", this); pinos_log_warn ("node %p: error setting callback", this);
@ -459,11 +531,7 @@ pinos_node_new (PinosCore *core,
(PinosDeferFunc) init_complete, (PinosDeferFunc) init_complete,
NULL); NULL);
} }
spa_list_insert (core->node_list.prev, &this->link);
this->global = pinos_core_add_global (core,
core->uri.node,
this);
return this; return this;
} }
@ -724,6 +792,10 @@ pinos_node_update_state (PinosNode *node,
old = node->state; old = node->state;
if (old != state) { if (old != state) {
PinosMessageNodeInfo m;
PinosNodeInfo info;
PinosResource *resource;
pinos_log_debug ("node %p: update state from %s -> %s", node, pinos_log_debug ("node %p: update state from %s -> %s", node,
pinos_node_state_as_string (old), pinos_node_state_as_string (old),
pinos_node_state_as_string (state)); pinos_node_state_as_string (state));
@ -732,6 +804,20 @@ pinos_node_update_state (PinosNode *node,
free (node->error); free (node->error);
node->error = error; node->error = error;
node->state = state; node->state = state;
pinos_signal_emit (&node->core->node_state_changed, node, old, state); pinos_signal_emit (&node->core->node_state_changed, node, old, state);
spa_zero (info);
m.info = &info;
info.change_mask = 1 << 1;
info.state = node->state;
spa_list_for_each (resource, &node->resource_list, link) {
info.id = resource->id;
pinos_resource_send_message (resource,
PINOS_MESSAGE_NODE_INFO,
&m,
true);
}
} }
} }

View file

@ -62,6 +62,8 @@ struct _PinosNode {
bool live; bool live;
SpaClock *clock; SpaClock *clock;
SpaList resource_list;
SpaList input_ports; SpaList input_ports;
SpaList output_ports; SpaList output_ports;

View file

@ -82,14 +82,14 @@ pinos_resource_destroy (PinosResource *resource)
SpaResult SpaResult
pinos_resource_send_message (PinosResource *resource, pinos_resource_send_message (PinosResource *resource,
PinosMessageType type, uint32_t opcode,
void *message, void *message,
bool flush) bool flush)
{ {
if (resource->send_func) if (resource->send_func)
return resource->send_func (resource, return resource->send_func (resource,
resource->id, resource->id,
type, opcode,
message, message,
flush, flush,
resource->send_data); resource->send_data);

View file

@ -35,13 +35,13 @@ typedef void (*PinosDestroy) (void *object);
typedef SpaResult (*PinosSendFunc) (void *object, typedef SpaResult (*PinosSendFunc) (void *object,
uint32_t id, uint32_t id,
PinosMessageType type, uint32_t opcode,
void *message, void *message,
bool flush, bool flush,
void *data); void *data);
typedef SpaResult (*PinosDispatchFunc) (void *object, typedef SpaResult (*PinosDispatchFunc) (void *object,
PinosMessageType type, uint32_t opcode,
void *message, void *message,
void *data); void *data);
@ -73,7 +73,7 @@ PinosResource * pinos_resource_new (PinosClient *client,
SpaResult pinos_resource_destroy (PinosResource *resource); SpaResult pinos_resource_destroy (PinosResource *resource);
SpaResult pinos_resource_send_message (PinosResource *resource, SpaResult pinos_resource_send_message (PinosResource *resource,
PinosMessageType type, uint32_t opcode,
void *message, void *message,
bool flush); bool flush);

View file

@ -31,17 +31,16 @@ typedef struct {
} Data; } Data;
static void static void
print_properties (PinosProperties *props, char mark) print_properties (SpaDict *props, char mark)
{ {
void *state = NULL; SpaDictItem *item;
const char *key;
if (props == NULL) if (props == NULL)
return; return;
printf ("%c\tproperties:\n", mark); printf ("%c\tproperties:\n", mark);
while ((key = pinos_properties_iterate (props, &state))) { spa_dict_for_each (item, props) {
printf ("%c\t\t%s = \"%s\"\n", mark, key, pinos_properties_get (props, key)); printf ("%c\t\t%s = \"%s\"\n", mark, item->key, item->value);
} }
} }
@ -53,51 +52,109 @@ typedef struct {
#define MARK_CHANGE(f) ((data->print_mark && ((info)->change_mask & (1 << (f)))) ? '*' : ' ') #define MARK_CHANGE(f) ((data->print_mark && ((info)->change_mask & (1 << (f)))) ? '*' : ' ')
static void static void
dump_daemon_info (PinosContext *c, const PinosDaemonInfo *info, void * user_data) dump_core_info (PinosContext *c,
SpaResult res,
const PinosCoreInfo *info,
void *user_data)
{ {
DumpData *data = user_data; DumpData *data = user_data;
if (info == NULL)
return;
printf ("\tid: %u\n", info->id); printf ("\tid: %u\n", info->id);
printf ("\ttype: %s\n", PINOS_CORE_URI);
if (data->print_all) { if (data->print_all) {
printf ("%c\tuser-name: \"%s\"\n", MARK_CHANGE (0), info->user_name); printf ("%c\tuser-name: \"%s\"\n", MARK_CHANGE (0), info->user_name);
printf ("%c\thost-name: \"%s\"\n", MARK_CHANGE (1), info->host_name); printf ("%c\thost-name: \"%s\"\n", MARK_CHANGE (1), info->host_name);
printf ("%c\tversion: \"%s\"\n", MARK_CHANGE (2), info->version); printf ("%c\tversion: \"%s\"\n", MARK_CHANGE (2), info->version);
printf ("%c\tname: \"%s\"\n", MARK_CHANGE (3), info->name); printf ("%c\tname: \"%s\"\n", MARK_CHANGE (3), info->name);
printf ("%c\tcookie: %u\n", MARK_CHANGE (4), info->cookie); printf ("%c\tcookie: %u\n", MARK_CHANGE (4), info->cookie);
print_properties (info->properties, MARK_CHANGE (5)); print_properties (info->props, MARK_CHANGE (5));
} }
} }
static void static void
dump_client_info (PinosContext *c, const PinosClientInfo *info, void * user_data) dump_client_info (PinosContext *c,
SpaResult res,
const PinosClientInfo *info,
void *user_data)
{ {
DumpData *data = user_data; DumpData *data = user_data;
if (info == NULL)
return;
printf ("\tid: %u\n", info->id); printf ("\tid: %u\n", info->id);
printf ("\ttype: %s\n", PINOS_CLIENT_URI);
if (data->print_all) { if (data->print_all) {
print_properties (info->properties, MARK_CHANGE (0)); print_properties (info->props, MARK_CHANGE (0));
} }
} }
static void static void
dump_node_info (PinosContext *c, const PinosNodeInfo *info, void * user_data) dump_node_info (PinosContext *c,
SpaResult res,
const PinosNodeInfo *info,
void *user_data)
{ {
DumpData *data = user_data; DumpData *data = user_data;
if (info == NULL) {
if (res != SPA_RESULT_ENUM_END)
printf ("\tError introspecting node: %d\n", res);
return;
}
printf ("\tid: %u\n", info->id); printf ("\tid: %u\n", info->id);
printf ("\ttype: %s\n", PINOS_NODE_URI);
if (data->print_all) { if (data->print_all) {
printf ("%c\tname: \"%s\"\n", MARK_CHANGE (0), info->name); printf ("%c\tname: \"%s\"\n", MARK_CHANGE (0), info->name);
print_properties (info->properties, MARK_CHANGE (1)); printf ("%c\tstate: \"%s\"\n", MARK_CHANGE (1), pinos_node_state_as_string (info->state));
printf ("%c\tstate: \"%s\"\n", MARK_CHANGE (2), pinos_node_state_as_string (info->state)); print_properties (info->props, MARK_CHANGE (2));
} }
} }
static void static void
dump_link_info (PinosContext *c, const PinosLinkInfo *info, void * user_data) dump_module_info (PinosContext *c,
SpaResult res,
const PinosModuleInfo *info,
void *user_data)
{ {
DumpData *data = user_data; DumpData *data = user_data;
if (info == NULL) {
if (res != SPA_RESULT_ENUM_END)
printf ("\tError introspecting module: %d\n", res);
return;
}
printf ("\tid: %u\n", info->id); printf ("\tid: %u\n", info->id);
printf ("\ttype: %s\n", PINOS_MODULE_URI);
if (data->print_all) {
printf ("%c\tname: \"%s\"\n", MARK_CHANGE (0), info->name);
printf ("%c\tfilename: \"%s\"\n", MARK_CHANGE (1), info->filename);
printf ("%c\targs: \"%s\"\n", MARK_CHANGE (2), info->args);
print_properties (info->props, MARK_CHANGE (3));
}
}
static void
dump_link_info (PinosContext *c,
SpaResult res,
const PinosLinkInfo *info,
void *user_data)
{
DumpData *data = user_data;
if (info == NULL) {
if (res != SPA_RESULT_ENUM_END)
printf ("\tError introspecting link: %d\n", res);
return;
}
printf ("\tid: %u\n", info->id);
printf ("\ttype: %s\n", PINOS_LINK_URI);
if (data->print_all) { if (data->print_all) {
printf ("%c\toutput-node-id: %u\n", MARK_CHANGE (0), info->output_node_id); printf ("%c\toutput-node-id: %u\n", MARK_CHANGE (0), info->output_node_id);
printf ("%c\toutput-port-id: %u\n", MARK_CHANGE (1), info->output_port_id); printf ("%c\toutput-port-id: %u\n", MARK_CHANGE (1), info->output_port_id);
@ -108,49 +165,66 @@ dump_link_info (PinosContext *c, const PinosLinkInfo *info, void * user_data)
static void static void
dump_object (PinosContext *context, dump_object (PinosContext *context,
uint32_t type,
uint32_t id, uint32_t id,
PinosSubscriptionFlags flags,
DumpData *data) DumpData *data)
{ {
if (flags & PINOS_SUBSCRIPTION_FLAG_DAEMON) { if (type == context->uri.node) {
pinos_context_get_node_info_by_id (context,
id,
dump_node_info,
data);
} }
else if (flags & PINOS_SUBSCRIPTION_FLAG_CLIENT) { if (type == context->uri.module) {
pinos_context_get_module_info_by_id (context,
id,
dump_module_info,
data);
} }
else if (flags & PINOS_SUBSCRIPTION_FLAG_NODE) { if (type == context->uri.client) {
pinos_context_get_client_info_by_id (context,
id,
dump_client_info,
data);
} }
else if (flags & PINOS_SUBSCRIPTION_FLAG_LINK) { if (type == context->uri.link) {
pinos_context_get_link_info_by_id (context,
id,
dump_link_info,
data);
} }
} }
static void static void
subscription_cb (PinosContext *context, subscription_cb (PinosContext *context,
PinosSubscriptionFlags flags, PinosSubscriptionEvent event,
PinosSubscriptionEvent type, uint32_t type,
uint32_t id, uint32_t id,
void *data) void *data)
{ {
DumpData dd; DumpData dd;
switch (type) { switch (event) {
case PINOS_SUBSCRIPTION_EVENT_NEW: case PINOS_SUBSCRIPTION_EVENT_NEW:
printf ("added:\n"); printf ("added:\n");
dd.print_mark = false; dd.print_mark = false;
dd.print_all = true; dd.print_all = true;
dump_object (context, id, flags, &dd); dump_object (context, type, id, &dd);
break; break;
case PINOS_SUBSCRIPTION_EVENT_CHANGE: case PINOS_SUBSCRIPTION_EVENT_CHANGE:
printf ("changed:\n"); printf ("changed:\n");
dd.print_mark = true; dd.print_mark = true;
dd.print_all = true; dd.print_all = true;
dump_object (context, id, flags, &dd); dump_object (context, type, id, &dd);
break; break;
case PINOS_SUBSCRIPTION_EVENT_REMOVE: case PINOS_SUBSCRIPTION_EVENT_REMOVE:
printf ("removed:\n"); printf ("removed:\n");
dd.print_mark = false; dd.print_mark = false;
dd.print_all = false; dd.print_all = false;
dump_object (context, id, flags, &dd); dump_object (context, type, id, &dd);
break; break;
} }
} }
@ -189,7 +263,6 @@ main (int argc, char *argv[])
on_state_changed); on_state_changed);
pinos_context_subscribe (data.context, pinos_context_subscribe (data.context,
PINOS_SUBSCRIPTION_FLAGS_ALL,
subscription_cb, subscription_cb,
&data); &data);

View file

@ -65,6 +65,7 @@ typedef enum {
SPA_RESULT_INVALID_BUFFER_ID = -28, SPA_RESULT_INVALID_BUFFER_ID = -28,
SPA_RESULT_WRONG_STATE = -29, SPA_RESULT_WRONG_STATE = -29,
SPA_RESULT_ASYNC_BUSY = -30, SPA_RESULT_ASYNC_BUSY = -30,
SPA_RESULT_INVALID_OBJECT_ID = -31,
} SpaResult; } SpaResult;
#define SPA_ASYNC_MASK (3 << 30) #define SPA_ASYNC_MASK (3 << 30)