mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	Work on introspection
This commit is contained in:
		
							parent
							
								
									7c29209023
								
							
						
					
					
						commit
						b969623ec8
					
				
					 39 changed files with 1726 additions and 574 deletions
				
			
		| 
						 | 
				
			
			@ -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));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
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) {
 | 
			
		||||
    len = pinos_serialize_dict_serialize (p, m->props);
 | 
			
		||||
    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) {
 | 
			
		||||
    len = pinos_serialize_dict_serialize (p, m->props);
 | 
			
		||||
    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));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PINOS_MESSAGE_DESTROY_DONE:
 | 
			
		||||
      if (conn->in.size < sizeof (PinosMessageDestroyDone))
 | 
			
		||||
    case PINOS_MESSAGE_REMOVE_ID:
 | 
			
		||||
      if (conn->in.size < sizeof (PinosMessageRemoveId))
 | 
			
		||||
        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;
 | 
			
		||||
 | 
			
		||||
    /* C -> S */
 | 
			
		||||
| 
						 | 
				
			
			@ -927,11 +1253,30 @@ pinos_connection_add_message (PinosConnection  *conn,
 | 
			
		|||
      memcpy (p, message, sizeof (PinosMessageDestroy));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PINOS_MESSAGE_DESTROY_DONE:
 | 
			
		||||
      p = connection_add_message (conn, dest_id, type, sizeof (PinosMessageDestroyDone));
 | 
			
		||||
      memcpy (p, message, sizeof (PinosMessageDestroyDone));
 | 
			
		||||
    case PINOS_MESSAGE_REMOVE_ID:
 | 
			
		||||
      p = connection_add_message (conn, dest_id, type, sizeof (PinosMessageRemoveId));
 | 
			
		||||
      memcpy (p, message, sizeof (PinosMessageRemoveId));
 | 
			
		||||
      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 */
 | 
			
		||||
    case PINOS_MESSAGE_NODE_UPDATE:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,6 +38,8 @@ typedef enum {
 | 
			
		|||
  PINOS_MESSAGE_SYNC,
 | 
			
		||||
  PINOS_MESSAGE_NOTIFY_DONE,
 | 
			
		||||
  PINOS_MESSAGE_GET_REGISTRY,
 | 
			
		||||
  PINOS_MESSAGE_REMOVE_ID,
 | 
			
		||||
  PINOS_MESSAGE_CORE_INFO,
 | 
			
		||||
 | 
			
		||||
  PINOS_MESSAGE_BIND,
 | 
			
		||||
  PINOS_MESSAGE_NOTIFY_GLOBAL,
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +52,11 @@ typedef enum {
 | 
			
		|||
  PINOS_MESSAGE_CREATE_CLIENT_NODE_DONE,
 | 
			
		||||
 | 
			
		||||
  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 */
 | 
			
		||||
  PINOS_MESSAGE_NODE_UPDATE,
 | 
			
		||||
| 
						 | 
				
			
			@ -78,6 +84,8 @@ typedef enum {
 | 
			
		|||
 | 
			
		||||
} PinosMessageType;
 | 
			
		||||
 | 
			
		||||
#include <pinos/client/introspect.h>
 | 
			
		||||
 | 
			
		||||
/* PINOS_MESSAGE_SYNC */
 | 
			
		||||
typedef struct {
 | 
			
		||||
  uint32_t     seq;
 | 
			
		||||
| 
						 | 
				
			
			@ -94,6 +102,36 @@ typedef struct {
 | 
			
		|||
  uint32_t     new_id;
 | 
			
		||||
} 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 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
  uint32_t     id;
 | 
			
		||||
| 
						 | 
				
			
			@ -145,12 +183,6 @@ typedef struct {
 | 
			
		|||
  uint32_t     id;
 | 
			
		||||
} PinosMessageDestroy;
 | 
			
		||||
 | 
			
		||||
/* PINOS_MESSAGE_DESTROY_DONE */
 | 
			
		||||
typedef struct {
 | 
			
		||||
  uint32_t     seq;
 | 
			
		||||
  uint32_t     id;
 | 
			
		||||
} PinosMessageDestroyDone;
 | 
			
		||||
 | 
			
		||||
/*  PINOS_MESSAGE_NODE_UPDATE */
 | 
			
		||||
typedef struct {
 | 
			
		||||
#define PINOS_MESSAGE_NODE_UPDATE_MAX_INPUTS   (1 << 0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,7 +38,6 @@ typedef struct {
 | 
			
		|||
 | 
			
		||||
  bool disconnecting;
 | 
			
		||||
 | 
			
		||||
  PinosSubscriptionFlags subscribe_mask;
 | 
			
		||||
  PinosSubscriptionFunc  subscribe_func;
 | 
			
		||||
  void                  *subscribe_data;
 | 
			
		||||
} PinosContextImpl;
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +101,8 @@ core_dispatch_func (void             *object,
 | 
			
		|||
                    void             *message,
 | 
			
		||||
                    void             *data)
 | 
			
		||||
{
 | 
			
		||||
  PinosContext *context = data;
 | 
			
		||||
  PinosContextImpl *impl = data;
 | 
			
		||||
  PinosContext *this = &impl->this;
 | 
			
		||||
 | 
			
		||||
  switch (type) {
 | 
			
		||||
    case PINOS_MESSAGE_NOTIFY_DONE:
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +110,142 @@ core_dispatch_func (void             *object,
 | 
			
		|||
      PinosMessageNotifyDone *nd = message;
 | 
			
		||||
 | 
			
		||||
      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;
 | 
			
		||||
    }
 | 
			
		||||
    default:
 | 
			
		||||
| 
						 | 
				
			
			@ -126,17 +261,61 @@ registry_dispatch_func (void             *object,
 | 
			
		|||
                        void             *message,
 | 
			
		||||
                        void             *data)
 | 
			
		||||
{
 | 
			
		||||
  PinosContextImpl *impl = data;
 | 
			
		||||
  PinosContext *this = &impl->this;
 | 
			
		||||
 | 
			
		||||
  switch (type) {
 | 
			
		||||
    case PINOS_MESSAGE_NOTIFY_GLOBAL:
 | 
			
		||||
    {
 | 
			
		||||
      PinosMessageNotifyGlobal *ng = message;
 | 
			
		||||
      PinosProxy *proxy = NULL;
 | 
			
		||||
 | 
			
		||||
      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;
 | 
			
		||||
    }
 | 
			
		||||
    case PINOS_MESSAGE_NOTIFY_GLOBAL_REMOVE:
 | 
			
		||||
    {
 | 
			
		||||
      PinosMessageNotifyGlobalRemove *ng = message;
 | 
			
		||||
      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;
 | 
			
		||||
    }
 | 
			
		||||
    default:
 | 
			
		||||
| 
						 | 
				
			
			@ -146,19 +325,6 @@ registry_dispatch_func (void             *object,
 | 
			
		|||
  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
 | 
			
		||||
on_context_data (SpaSource *source,
 | 
			
		||||
                 int        fd,
 | 
			
		||||
| 
						 | 
				
			
			@ -190,11 +356,15 @@ on_context_data (SpaSource *source,
 | 
			
		|||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      proxy = find_proxy (this, id);
 | 
			
		||||
      proxy = pinos_map_lookup (&this->objects, id);
 | 
			
		||||
      if (proxy == NULL) {
 | 
			
		||||
        pinos_log_error ("context %p: could not find proxy %u", this, id);
 | 
			
		||||
        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);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -250,6 +420,8 @@ pinos_context_new (PinosLoop       *loop,
 | 
			
		|||
  pinos_fill_context_properties (properties);
 | 
			
		||||
  this->properties = properties;
 | 
			
		||||
 | 
			
		||||
  pinos_uri_init (&this->uri);
 | 
			
		||||
 | 
			
		||||
  this->loop = loop;
 | 
			
		||||
 | 
			
		||||
  this->state = PINOS_CONTEXT_STATE_UNCONNECTED;
 | 
			
		||||
| 
						 | 
				
			
			@ -365,15 +537,15 @@ pinos_context_connect (PinosContext      *context)
 | 
			
		|||
 | 
			
		||||
  context->core_proxy = pinos_proxy_new (context,
 | 
			
		||||
                                         SPA_ID_INVALID,
 | 
			
		||||
                                         0);
 | 
			
		||||
                                         context->uri.core);
 | 
			
		||||
  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,
 | 
			
		||||
                                             SPA_ID_INVALID,
 | 
			
		||||
                                             0);
 | 
			
		||||
                                             context->uri.registry);
 | 
			
		||||
  context->registry_proxy->dispatch_func = registry_dispatch_func;
 | 
			
		||||
  context->registry_proxy->dispatch_data = context;
 | 
			
		||||
  context->registry_proxy->dispatch_data = impl;
 | 
			
		||||
 | 
			
		||||
  grm.seq = 0;
 | 
			
		||||
  grm.new_id = context->registry_proxy->id;
 | 
			
		||||
| 
						 | 
				
			
			@ -409,23 +581,84 @@ pinos_context_disconnect (PinosContext *context)
 | 
			
		|||
 | 
			
		||||
void
 | 
			
		||||
pinos_context_subscribe (PinosContext           *context,
 | 
			
		||||
                         PinosSubscriptionFlags  mask,
 | 
			
		||||
                         PinosSubscriptionFunc   func,
 | 
			
		||||
                         void                   *data)
 | 
			
		||||
{
 | 
			
		||||
  PinosContextImpl *impl = SPA_CONTAINER_OF (context, PinosContextImpl, this);
 | 
			
		||||
 | 
			
		||||
  impl->subscribe_mask = mask;
 | 
			
		||||
  impl->subscribe_func = func;
 | 
			
		||||
  impl->subscribe_data = data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
pinos_context_get_daemon_info (PinosContext            *context,
 | 
			
		||||
                               PinosDaemonInfoCallback  cb,
 | 
			
		||||
                               void                    *user_data)
 | 
			
		||||
pinos_context_get_core_info (PinosContext            *context,
 | 
			
		||||
                             PinosCoreInfoCallback    cb,
 | 
			
		||||
                             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
 | 
			
		||||
| 
						 | 
				
			
			@ -433,7 +666,7 @@ pinos_context_list_client_info (PinosContext            *context,
 | 
			
		|||
                                PinosClientInfoCallback  cb,
 | 
			
		||||
                                void                    *user_data)
 | 
			
		||||
{
 | 
			
		||||
  cb (context, SPA_RESULT_OK, NULL, user_data);
 | 
			
		||||
  do_list (context, context->uri.client, (ListFunc) cb, user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
| 
						 | 
				
			
			@ -442,7 +675,17 @@ pinos_context_get_client_info_by_id (PinosContext            *context,
 | 
			
		|||
                                     PinosClientInfoCallback  cb,
 | 
			
		||||
                                     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
 | 
			
		||||
| 
						 | 
				
			
			@ -450,7 +693,7 @@ pinos_context_list_node_info (PinosContext          *context,
 | 
			
		|||
                              PinosNodeInfoCallback  cb,
 | 
			
		||||
                              void                  *user_data)
 | 
			
		||||
{
 | 
			
		||||
  cb (context, SPA_RESULT_OK, NULL, user_data);
 | 
			
		||||
  do_list (context, context->uri.node, (ListFunc) cb, user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
| 
						 | 
				
			
			@ -459,7 +702,17 @@ pinos_context_get_node_info_by_id (PinosContext          *context,
 | 
			
		|||
                                   PinosNodeInfoCallback  cb,
 | 
			
		||||
                                   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
 | 
			
		||||
| 
						 | 
				
			
			@ -467,7 +720,7 @@ pinos_context_list_link_info (PinosContext          *context,
 | 
			
		|||
                              PinosLinkInfoCallback  cb,
 | 
			
		||||
                              void                  *user_data)
 | 
			
		||||
{
 | 
			
		||||
  cb (context, SPA_RESULT_OK, NULL, user_data);
 | 
			
		||||
  do_list (context, context->uri.link, (ListFunc) cb, user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
| 
						 | 
				
			
			@ -476,5 +729,15 @@ pinos_context_get_link_info_by_id (PinosContext          *context,
 | 
			
		|||
                                   PinosLinkInfoCallback  cb,
 | 
			
		||||
                                   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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,10 +28,9 @@ typedef struct _PinosContext PinosContext;
 | 
			
		|||
 | 
			
		||||
#include <pinos/client/map.h>
 | 
			
		||||
#include <pinos/client/loop.h>
 | 
			
		||||
#include <pinos/client/subscribe.h>
 | 
			
		||||
#include <pinos/client/properties.h>
 | 
			
		||||
#include <pinos/client/connection.h>
 | 
			
		||||
#include <pinos/client/proxy.h>
 | 
			
		||||
#include <pinos/client/uri.h>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * PinosContextState:
 | 
			
		||||
| 
						 | 
				
			
			@ -60,6 +59,8 @@ struct _PinosContext {
 | 
			
		|||
  char            *name;
 | 
			
		||||
  PinosProperties *properties;
 | 
			
		||||
 | 
			
		||||
  PinosURI         uri;
 | 
			
		||||
 | 
			
		||||
  PinosLoop       *loop;
 | 
			
		||||
 | 
			
		||||
  PinosProxy      *core_proxy;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -103,3 +103,177 @@ pinos_link_state_as_string (PinosLinkState 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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,19 @@
 | 
			
		|||
extern "C" {
 | 
			
		||||
#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:
 | 
			
		||||
 * @PINOS_NODE_STATE_ERROR: the node is in error
 | 
			
		||||
| 
						 | 
				
			
			@ -40,14 +53,14 @@ extern "C" {
 | 
			
		|||
 *
 | 
			
		||||
 * The different node states
 | 
			
		||||
 */
 | 
			
		||||
typedef enum {
 | 
			
		||||
enum _PinosNodeState {
 | 
			
		||||
  PINOS_NODE_STATE_ERROR = -1,
 | 
			
		||||
  PINOS_NODE_STATE_CREATING = 0,
 | 
			
		||||
  PINOS_NODE_STATE_SUSPENDED = 1,
 | 
			
		||||
  PINOS_NODE_STATE_INITIALIZING = 2,
 | 
			
		||||
  PINOS_NODE_STATE_IDLE = 3,
 | 
			
		||||
  PINOS_NODE_STATE_RUNNING = 4,
 | 
			
		||||
} PinosNodeState;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 */
 | 
			
		||||
typedef enum {
 | 
			
		||||
enum _PinosDirection {
 | 
			
		||||
  PINOS_DIRECTION_INVALID = SPA_DIRECTION_INVALID,
 | 
			
		||||
  PINOS_DIRECTION_INPUT = SPA_DIRECTION_INPUT,
 | 
			
		||||
  PINOS_DIRECTION_OUTPUT = SPA_DIRECTION_OUTPUT
 | 
			
		||||
} PinosDirection;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const char * pinos_direction_as_string (PinosDirection direction);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -79,7 +92,7 @@ const char * pinos_direction_as_string (PinosDirection direction);
 | 
			
		|||
 *
 | 
			
		||||
 * The different link states
 | 
			
		||||
 */
 | 
			
		||||
typedef enum {
 | 
			
		||||
enum _PinosLinkState {
 | 
			
		||||
  PINOS_LINK_STATE_ERROR = -2,
 | 
			
		||||
  PINOS_LINK_STATE_UNLINKED = -1,
 | 
			
		||||
  PINOS_LINK_STATE_INIT = 0,
 | 
			
		||||
| 
						 | 
				
			
			@ -87,28 +100,25 @@ typedef enum {
 | 
			
		|||
  PINOS_LINK_STATE_ALLOCATING = 2,
 | 
			
		||||
  PINOS_LINK_STATE_PAUSED = 3,
 | 
			
		||||
  PINOS_LINK_STATE_RUNNING = 4,
 | 
			
		||||
} PinosLinkState;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const char * pinos_link_state_as_string (PinosLinkState state);
 | 
			
		||||
 | 
			
		||||
#include <pinos/client/context.h>
 | 
			
		||||
#include <pinos/client/properties.h>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * PinosDaemonInfo:
 | 
			
		||||
 * @id: generic id of the daemon
 | 
			
		||||
 * PinosCoreInfo:
 | 
			
		||||
 * @id: generic id of the core
 | 
			
		||||
 * @change_mask: bitfield of changed fields since last call
 | 
			
		||||
 * @user_name: name of the user that started the daemon
 | 
			
		||||
 * @host_name: name of the machine the daemon is running on
 | 
			
		||||
 * @version: version of the daemon
 | 
			
		||||
 * @name: name of the daemon
 | 
			
		||||
 * @user_name: name of the user that started the core
 | 
			
		||||
 * @host_name: name of the machine the core is running on
 | 
			
		||||
 * @version: version of the core
 | 
			
		||||
 * @name: name of the core
 | 
			
		||||
 * @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.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
struct _PinosCoreInfo {
 | 
			
		||||
  uint32_t id;
 | 
			
		||||
  uint64_t change_mask;
 | 
			
		||||
  const char *user_name;
 | 
			
		||||
| 
						 | 
				
			
			@ -116,41 +126,93 @@ typedef struct {
 | 
			
		|||
  const char *version;
 | 
			
		||||
  const char *name;
 | 
			
		||||
  uint32_t cookie;
 | 
			
		||||
  PinosProperties *properties;
 | 
			
		||||
} PinosDaemonInfo;
 | 
			
		||||
  SpaDict *props;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 * @info: a #PinosDaemonInfo
 | 
			
		||||
 * @info: a #PinosModuleInfo
 | 
			
		||||
 * @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,
 | 
			
		||||
					  SpaResult              res,
 | 
			
		||||
                                          const PinosDaemonInfo *info,
 | 
			
		||||
typedef void (*PinosModuleInfoCallback)  (PinosContext          *c,
 | 
			
		||||
                                          SpaResult              res,
 | 
			
		||||
                                          const PinosModuleInfo *info,
 | 
			
		||||
                                          void                  *user_data);
 | 
			
		||||
 | 
			
		||||
void            pinos_context_get_daemon_info (PinosContext            *context,
 | 
			
		||||
                                               PinosDaemonInfoCallback  cb,
 | 
			
		||||
                                               void                    *user_data);
 | 
			
		||||
void            pinos_context_list_module_info      (PinosContext            *context,
 | 
			
		||||
                                                     PinosModuleInfoCallback  cb,
 | 
			
		||||
                                                     void                    *user_data);
 | 
			
		||||
void            pinos_context_get_module_info_by_id (PinosContext            *context,
 | 
			
		||||
                                                     uint32_t                 id,
 | 
			
		||||
                                                     PinosModuleInfoCallback  cb,
 | 
			
		||||
                                                     void                    *user_data);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * PinosClientInfo:
 | 
			
		||||
 * @id: generic id of the client
 | 
			
		||||
 * @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
 | 
			
		||||
 * versions.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
struct _PinosClientInfo {
 | 
			
		||||
  uint32_t id;
 | 
			
		||||
  uint64_t change_mask;
 | 
			
		||||
  PinosProperties *properties;
 | 
			
		||||
} PinosClientInfo;
 | 
			
		||||
  SpaDict *props;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PinosClientInfo *  pinos_client_info_update (PinosClientInfo       *info,
 | 
			
		||||
                                             const PinosClientInfo *update);
 | 
			
		||||
void               pinos_client_info_free   (PinosClientInfo       *info);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * PinosClientInfoCallback:
 | 
			
		||||
| 
						 | 
				
			
			@ -178,19 +240,23 @@ void            pinos_context_get_client_info_by_id (PinosContext            *co
 | 
			
		|||
 * @id: generic id of the node
 | 
			
		||||
 * @change_mask: bitfield of changed fields since last call
 | 
			
		||||
 * @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
 | 
			
		||||
 *
 | 
			
		||||
 * The node information. Extra information can be added in later
 | 
			
		||||
 * versions.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
struct _PinosNodeInfo {
 | 
			
		||||
  uint32_t id;
 | 
			
		||||
  uint64_t change_mask;
 | 
			
		||||
  const char *name;
 | 
			
		||||
  PinosProperties *properties;
 | 
			
		||||
  PinosNodeState state;
 | 
			
		||||
} PinosNodeInfo;
 | 
			
		||||
  SpaDict *props;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PinosNodeInfo *    pinos_node_info_update (PinosNodeInfo       *info,
 | 
			
		||||
                                           const PinosNodeInfo *update);
 | 
			
		||||
void               pinos_node_info_free   (PinosNodeInfo       *info);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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
 | 
			
		||||
 * versions.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
struct _PinosLinkInfo {
 | 
			
		||||
  uint32_t id;
 | 
			
		||||
  uint64_t change_mask;
 | 
			
		||||
  uint32_t output_node_id;
 | 
			
		||||
  uint32_t output_port_id;
 | 
			
		||||
  uint32_t input_node_id;
 | 
			
		||||
  uint32_t input_port_id;
 | 
			
		||||
} PinosLinkInfo;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,7 @@ pinos_headers = [
 | 
			
		|||
  'subscribe.h',
 | 
			
		||||
  'thread-mainloop.h',
 | 
			
		||||
  'transport.h',
 | 
			
		||||
  'uri.h',
 | 
			
		||||
  'utils.h',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -33,6 +34,7 @@ pinos_sources = [
 | 
			
		|||
  'rtkit.c',
 | 
			
		||||
  'thread-mainloop.c',
 | 
			
		||||
  'transport.c',
 | 
			
		||||
  'uri.c',
 | 
			
		||||
  'utils.c',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,37 +21,40 @@
 | 
			
		|||
#include "pinos/client/properties.h"
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  char *key;
 | 
			
		||||
  char *value;
 | 
			
		||||
} PropItem;
 | 
			
		||||
  PinosProperties this;
 | 
			
		||||
 | 
			
		||||
struct _PinosProperties {
 | 
			
		||||
  PinosArray items;
 | 
			
		||||
};
 | 
			
		||||
} PinosPropertiesImpl;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
add_func (PinosProperties *props, char *key, char *value)
 | 
			
		||||
add_func (PinosProperties *this, char *key, char *value)
 | 
			
		||||
{
 | 
			
		||||
  PropItem *item;
 | 
			
		||||
  item = pinos_array_add (&props->items, sizeof (PropItem));
 | 
			
		||||
  SpaDictItem *item;
 | 
			
		||||
  PinosPropertiesImpl *impl = SPA_CONTAINER_OF (this, PinosPropertiesImpl, this);
 | 
			
		||||
 | 
			
		||||
  item = pinos_array_add (&impl->items, sizeof (SpaDictItem));
 | 
			
		||||
  item->key = key;
 | 
			
		||||
  item->value = value;
 | 
			
		||||
 | 
			
		||||
  this->dict.items = impl->items.data;
 | 
			
		||||
  this->dict.n_items = pinos_array_get_len (&impl->items, SpaDictItem);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clear_item (PropItem *item)
 | 
			
		||||
clear_item (SpaDictItem *item)
 | 
			
		||||
{
 | 
			
		||||
  free (item->key);
 | 
			
		||||
  free (item->value);
 | 
			
		||||
  free ((char*)item->key);
 | 
			
		||||
  free ((char*)item->value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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++) {
 | 
			
		||||
    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)
 | 
			
		||||
      return i;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -70,22 +73,22 @@ find_index (PinosProperties *props, const char *key)
 | 
			
		|||
PinosProperties *
 | 
			
		||||
pinos_properties_new (const char *key, ...)
 | 
			
		||||
{
 | 
			
		||||
  PinosProperties *props;
 | 
			
		||||
  PinosPropertiesImpl *impl;
 | 
			
		||||
  va_list varargs;
 | 
			
		||||
  const char *value;
 | 
			
		||||
 | 
			
		||||
  props = calloc (1, sizeof (PinosProperties));
 | 
			
		||||
  pinos_array_init (&props->items);
 | 
			
		||||
  impl = calloc (1, sizeof (PinosPropertiesImpl));
 | 
			
		||||
  pinos_array_init (&impl->items);
 | 
			
		||||
 | 
			
		||||
  va_start (varargs, key);
 | 
			
		||||
  while (key != NULL) {
 | 
			
		||||
    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 *);
 | 
			
		||||
  }
 | 
			
		||||
  va_end (varargs);
 | 
			
		||||
 | 
			
		||||
  return props;
 | 
			
		||||
  return &impl->this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -99,11 +102,12 @@ pinos_properties_new (const char *key, ...)
 | 
			
		|||
PinosProperties *
 | 
			
		||||
pinos_properties_copy (PinosProperties *properties)
 | 
			
		||||
{
 | 
			
		||||
  PinosPropertiesImpl *impl = SPA_CONTAINER_OF (properties, PinosPropertiesImpl, this);
 | 
			
		||||
  PinosProperties *copy;
 | 
			
		||||
  PropItem *item;
 | 
			
		||||
  SpaDictItem *item;
 | 
			
		||||
 | 
			
		||||
  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));
 | 
			
		||||
 | 
			
		||||
  return copy;
 | 
			
		||||
| 
						 | 
				
			
			@ -145,13 +149,14 @@ pinos_properties_merge (PinosProperties *oldprops,
 | 
			
		|||
void
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
  pinos_array_clear (&properties->items);
 | 
			
		||||
  free (properties);
 | 
			
		||||
  pinos_array_clear (&impl->items);
 | 
			
		||||
  free (impl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			@ -159,21 +164,22 @@ do_replace (PinosProperties *properties,
 | 
			
		|||
            char            *key,
 | 
			
		||||
            char            *value)
 | 
			
		||||
{
 | 
			
		||||
  PinosPropertiesImpl *impl = SPA_CONTAINER_OF (properties, PinosPropertiesImpl, this);
 | 
			
		||||
  int index = find_index (properties, key);
 | 
			
		||||
 | 
			
		||||
  if (index == -1) {
 | 
			
		||||
    add_func (properties, key, value);
 | 
			
		||||
  } else {
 | 
			
		||||
    PropItem *item = pinos_array_get_unchecked (&properties->items, index, PropItem);
 | 
			
		||||
    SpaDictItem *item = pinos_array_get_unchecked (&impl->items, index, SpaDictItem);
 | 
			
		||||
 | 
			
		||||
    clear_item (item);
 | 
			
		||||
    if (value == NULL) {
 | 
			
		||||
      PropItem *other = pinos_array_get_unchecked (&properties->items,
 | 
			
		||||
                                                   pinos_array_get_len (&properties->items, PropItem) - 1,
 | 
			
		||||
                                                   PropItem);
 | 
			
		||||
      SpaDictItem *other = pinos_array_get_unchecked (&impl->items,
 | 
			
		||||
                                                   pinos_array_get_len (&impl->items, SpaDictItem) - 1,
 | 
			
		||||
                                                   SpaDictItem);
 | 
			
		||||
      item->key = other->key;
 | 
			
		||||
      item->value = other->value;
 | 
			
		||||
      properties->items.size -= sizeof (PropItem);
 | 
			
		||||
      impl->items.size -= sizeof (SpaDictItem);
 | 
			
		||||
    } else {
 | 
			
		||||
      item->key = key;
 | 
			
		||||
      item->value = value;
 | 
			
		||||
| 
						 | 
				
			
			@ -238,12 +244,13 @@ const char *
 | 
			
		|||
pinos_properties_get (PinosProperties *properties,
 | 
			
		||||
                      const char      *key)
 | 
			
		||||
{
 | 
			
		||||
  PinosPropertiesImpl *impl = SPA_CONTAINER_OF (properties, PinosPropertiesImpl, this);
 | 
			
		||||
  int index = find_index (properties, key);
 | 
			
		||||
 | 
			
		||||
  if (index == -1)
 | 
			
		||||
    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,
 | 
			
		||||
                          void               **state)
 | 
			
		||||
{
 | 
			
		||||
  PinosPropertiesImpl *impl = SPA_CONTAINER_OF (properties, PinosPropertiesImpl, this);
 | 
			
		||||
  unsigned int index;
 | 
			
		||||
 | 
			
		||||
  if (*state == NULL)
 | 
			
		||||
| 
						 | 
				
			
			@ -271,10 +279,10 @@ pinos_properties_iterate (PinosProperties     *properties,
 | 
			
		|||
  else
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
  *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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,10 @@ extern "C" {
 | 
			
		|||
 | 
			
		||||
typedef struct _PinosProperties PinosProperties;
 | 
			
		||||
 | 
			
		||||
struct _PinosProperties {
 | 
			
		||||
  SpaDict dict;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PinosProperties * pinos_properties_new      (const char *key, ...);
 | 
			
		||||
PinosProperties * pinos_properties_copy     (PinosProperties *properties);
 | 
			
		||||
PinosProperties * pinos_properties_merge    (PinosProperties *oldprops,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,12 +63,12 @@ pinos_proxy_destroy (PinosProxy *proxy)
 | 
			
		|||
 | 
			
		||||
SpaResult
 | 
			
		||||
pinos_proxy_send_message (PinosProxy        *proxy,
 | 
			
		||||
                          PinosMessageType   type,
 | 
			
		||||
                          uint32_t           opcode,
 | 
			
		||||
                          void              *message,
 | 
			
		||||
                          bool               flush)
 | 
			
		||||
{
 | 
			
		||||
  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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,21 +24,20 @@
 | 
			
		|||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <pinos/client/connection.h>
 | 
			
		||||
 | 
			
		||||
typedef struct _PinosProxy PinosProxy;
 | 
			
		||||
 | 
			
		||||
typedef SpaResult (*PinosSendFunc)     (void             *object,
 | 
			
		||||
                                        uint32_t          id,
 | 
			
		||||
                                        PinosMessageType  type,
 | 
			
		||||
                                        uint32_t          opcode,
 | 
			
		||||
                                        void             *message,
 | 
			
		||||
                                        bool              flush,
 | 
			
		||||
                                        void             *data);
 | 
			
		||||
 | 
			
		||||
typedef SpaResult (*PinosDispatchFunc) (void             *object,
 | 
			
		||||
                                        PinosMessageType  type,
 | 
			
		||||
                                        uint32_t          opcode,
 | 
			
		||||
                                        void             *message,
 | 
			
		||||
                                        void             *data);
 | 
			
		||||
#include <pinos/client/connection.h>
 | 
			
		||||
#include <pinos/client/context.h>
 | 
			
		||||
 | 
			
		||||
struct _PinosProxy {
 | 
			
		||||
| 
						 | 
				
			
			@ -53,6 +52,8 @@ struct _PinosProxy {
 | 
			
		|||
  PinosDispatchFunc  dispatch_func;
 | 
			
		||||
  void              *dispatch_data;
 | 
			
		||||
 | 
			
		||||
  void              *user_data;
 | 
			
		||||
 | 
			
		||||
  PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
 | 
			
		||||
                                 PinosProxy    *proxy));
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -63,7 +64,7 @@ PinosProxy *      pinos_proxy_new                     (PinosContext      *contex
 | 
			
		|||
void              pinos_proxy_destroy                 (PinosProxy        *proxy);
 | 
			
		||||
 | 
			
		||||
SpaResult         pinos_proxy_send_message            (PinosProxy        *proxy,
 | 
			
		||||
                                                       PinosMessageType   type,
 | 
			
		||||
                                                       uint32_t           opcode,
 | 
			
		||||
                                                       void              *message,
 | 
			
		||||
                                                       bool               flush);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -610,13 +610,18 @@ stream_dispatch_func (void             *object,
 | 
			
		|||
    case PINOS_MESSAGE_GET_REGISTRY:
 | 
			
		||||
    case PINOS_MESSAGE_BIND:
 | 
			
		||||
    case PINOS_MESSAGE_DESTROY:
 | 
			
		||||
    case PINOS_MESSAGE_DESTROY_DONE:
 | 
			
		||||
    case PINOS_MESSAGE_REMOVE_ID:
 | 
			
		||||
    case PINOS_MESSAGE_CREATE_NODE:
 | 
			
		||||
    case PINOS_MESSAGE_CREATE_CLIENT_NODE:
 | 
			
		||||
    case PINOS_MESSAGE_NODE_UPDATE:
 | 
			
		||||
    case PINOS_MESSAGE_PORT_UPDATE:
 | 
			
		||||
    case PINOS_MESSAGE_PORT_STATUS_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);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,21 +26,21 @@
 | 
			
		|||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    PINOS_SUBSCRIPTION_STATE_UNCONNECTED     = 0,
 | 
			
		||||
    PINOS_SUBSCRIPTION_STATE_CONNECTING      = 1,
 | 
			
		||||
    PINOS_SUBSCRIPTION_STATE_READY           = 2,
 | 
			
		||||
    PINOS_SUBSCRIPTION_STATE_ERROR           = 3,
 | 
			
		||||
} PinosSubscriptionState;
 | 
			
		||||
#define PINOS_CORE_URI                            "http://pinos.org/ns/core"
 | 
			
		||||
#define PINOS_CORE_PREFIX                         PINOS_CORE_URI "#"
 | 
			
		||||
#define PINOS_CORE_REGISTRY                       PINOS_CORE_PREFIX "Registry"
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    PINOS_SUBSCRIPTION_FLAG_DAEMON          = (1 << 0),
 | 
			
		||||
    PINOS_SUBSCRIPTION_FLAG_CLIENT          = (1 << 1),
 | 
			
		||||
    PINOS_SUBSCRIPTION_FLAG_NODE            = (1 << 2),
 | 
			
		||||
    PINOS_SUBSCRIPTION_FLAG_LINK            = (1 << 3)
 | 
			
		||||
} PinosSubscriptionFlags;
 | 
			
		||||
#define PINOS_NODE_URI                            "http://pinos.org/ns/node"
 | 
			
		||||
#define PINOS_NODE_PREFIX                         PINOS_NODE_URI "#"
 | 
			
		||||
 | 
			
		||||
#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 {
 | 
			
		||||
    PINOS_SUBSCRIPTION_EVENT_NEW           = 0,
 | 
			
		||||
| 
						 | 
				
			
			@ -49,13 +49,12 @@ typedef enum {
 | 
			
		|||
} PinosSubscriptionEvent;
 | 
			
		||||
 | 
			
		||||
typedef void (*PinosSubscriptionFunc)  (PinosContext           *context,
 | 
			
		||||
                                        PinosSubscriptionFlags  flags,
 | 
			
		||||
                                        PinosSubscriptionEvent  event,
 | 
			
		||||
                                        uint32_t                type,
 | 
			
		||||
                                        uint32_t                id,
 | 
			
		||||
                                        void                   *data);
 | 
			
		||||
 | 
			
		||||
void         pinos_context_subscribe  (PinosContext           *context,
 | 
			
		||||
                                       PinosSubscriptionFlags  mask,
 | 
			
		||||
                                       PinosSubscriptionFunc   func,
 | 
			
		||||
                                       void                   *data);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,8 +20,9 @@
 | 
			
		|||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "pinos/client/pinos.h"
 | 
			
		||||
#include "pinos/client/uri.h"
 | 
			
		||||
 | 
			
		||||
#include "pinos/server/core.h"
 | 
			
		||||
#include "pinos/server/uri.h"
 | 
			
		||||
#include "pinos/server/node.h"
 | 
			
		||||
#include "pinos/server/node-factory.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_clock = spa_id_map_get_id (uri->map, SPA_CLOCK_URI);
 | 
			
		||||
  uri->spa_monitor = spa_id_map_get_id (uri->map, SPA_MONITOR_URI);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
#load-module libpinos-module-protocol-dbus
 | 
			
		||||
load-module libpinos-module-protocol-native
 | 
			
		||||
load-module libpinos-module-suspend-on-idle
 | 
			
		||||
load-module libpinos-module-spa
 | 
			
		||||
load-module libpinos-module-spa --pattern snow
 | 
			
		||||
load-module libpinos-module-autolink
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -190,8 +190,8 @@ new_node (const PinosNodeInfo *info)
 | 
			
		|||
{
 | 
			
		||||
  GstCaps *caps;
 | 
			
		||||
  GstStructure *props;
 | 
			
		||||
  gpointer state = NULL;
 | 
			
		||||
  const gchar *klass;
 | 
			
		||||
  SpaDictItem *item;
 | 
			
		||||
 | 
			
		||||
  /* FIXME, iterate ports */
 | 
			
		||||
#if 0
 | 
			
		||||
| 
						 | 
				
			
			@ -202,18 +202,10 @@ new_node (const PinosNodeInfo *info)
 | 
			
		|||
    caps = gst_caps_new_any();
 | 
			
		||||
 | 
			
		||||
  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) {
 | 
			
		||||
    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");
 | 
			
		||||
  klass = spa_dict_lookup (info->props, "gstreamer.device.class");
 | 
			
		||||
  if (klass == NULL)
 | 
			
		||||
    klass = "unknown/unknown";
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -263,8 +255,8 @@ find_device (GstDeviceProvider *provider, uint32_t id)
 | 
			
		|||
 | 
			
		||||
static void
 | 
			
		||||
context_subscribe_cb (PinosContext           *context,
 | 
			
		||||
                      PinosSubscriptionFlags  flags,
 | 
			
		||||
                      PinosSubscriptionEvent  type,
 | 
			
		||||
                      PinosSubscriptionEvent  event,
 | 
			
		||||
                      uint32_t                type,
 | 
			
		||||
                      uint32_t                id,
 | 
			
		||||
                      void                   *user_data)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -272,19 +264,19 @@ context_subscribe_cb (PinosContext           *context,
 | 
			
		|||
  GstDeviceProvider *provider = user_data;
 | 
			
		||||
  GstPinosDevice *dev;
 | 
			
		||||
 | 
			
		||||
  if (flags != PINOS_SUBSCRIPTION_FLAG_NODE)
 | 
			
		||||
  if (type != context->uri.node)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  dev = find_device (provider, id);
 | 
			
		||||
 | 
			
		||||
  if (type == PINOS_SUBSCRIPTION_EVENT_NEW) {
 | 
			
		||||
    if (flags == PINOS_SUBSCRIPTION_FLAG_NODE && dev == NULL)
 | 
			
		||||
  if (event == PINOS_SUBSCRIPTION_EVENT_NEW) {
 | 
			
		||||
    if (dev == NULL)
 | 
			
		||||
      pinos_context_get_node_info_by_id (context,
 | 
			
		||||
                                         id,
 | 
			
		||||
                                         get_node_info_cb,
 | 
			
		||||
                                         self);
 | 
			
		||||
  } else if (type == PINOS_SUBSCRIPTION_EVENT_REMOVE) {
 | 
			
		||||
    if (flags == PINOS_SUBSCRIPTION_FLAG_NODE && dev != NULL) {
 | 
			
		||||
  } else if (event == PINOS_SUBSCRIPTION_EVENT_REMOVE) {
 | 
			
		||||
    if (dev != NULL) {
 | 
			
		||||
      gst_device_provider_device_remove (GST_DEVICE_PROVIDER (self),
 | 
			
		||||
                                         GST_DEVICE (dev));
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -313,15 +305,15 @@ list_node_info_cb (PinosContext        *c,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
get_daemon_info_cb (PinosContext          *c,
 | 
			
		||||
                    SpaResult              res,
 | 
			
		||||
                    const PinosDaemonInfo *info,
 | 
			
		||||
                    void                  *user_data)
 | 
			
		||||
get_core_info_cb (PinosContext        *c,
 | 
			
		||||
                  SpaResult            res,
 | 
			
		||||
                  const PinosCoreInfo *info,
 | 
			
		||||
                  void                *user_data)
 | 
			
		||||
{
 | 
			
		||||
  GstDeviceProvider *provider = user_data;
 | 
			
		||||
  const gchar *value;
 | 
			
		||||
 | 
			
		||||
  value = pinos_properties_get (info->properties, "gstreamer.deviceproviders");
 | 
			
		||||
  value = spa_dict_lookup (info->props, "gstreamer.deviceproviders");
 | 
			
		||||
  if (value) {
 | 
			
		||||
    gchar **providers = g_strsplit (value, ",", -1);
 | 
			
		||||
    gint i;
 | 
			
		||||
| 
						 | 
				
			
			@ -371,9 +363,9 @@ gst_pinos_device_provider_probe (GstDeviceProvider * provider)
 | 
			
		|||
  }
 | 
			
		||||
  GST_DEBUG_OBJECT (self, "connected");
 | 
			
		||||
 | 
			
		||||
  pinos_context_get_daemon_info (c,
 | 
			
		||||
                                 get_daemon_info_cb,
 | 
			
		||||
                                 self);
 | 
			
		||||
  pinos_context_get_core_info (c,
 | 
			
		||||
                               get_core_info_cb,
 | 
			
		||||
                               self);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  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_context_subscribe (self->context,
 | 
			
		||||
                           PINOS_SUBSCRIPTION_FLAGS_ALL,
 | 
			
		||||
                           context_subscribe_cb,
 | 
			
		||||
                           self);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -475,9 +466,9 @@ gst_pinos_device_provider_start (GstDeviceProvider * provider)
 | 
			
		|||
    pinos_thread_main_loop_wait (self->main_loop);
 | 
			
		||||
  }
 | 
			
		||||
  GST_DEBUG_OBJECT (self, "connected");
 | 
			
		||||
  pinos_context_get_daemon_info (self->context,
 | 
			
		||||
                                 get_daemon_info_cb,
 | 
			
		||||
                                 self);
 | 
			
		||||
  pinos_context_get_core_info (self->context,
 | 
			
		||||
                               get_core_info_cb,
 | 
			
		||||
                               self);
 | 
			
		||||
  pinos_thread_main_loop_unlock (self->main_loop);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,14 +29,12 @@
 | 
			
		|||
typedef struct {
 | 
			
		||||
  PinosCore       *core;
 | 
			
		||||
  PinosProperties *properties;
 | 
			
		||||
  PinosGlobal     *global;
 | 
			
		||||
 | 
			
		||||
  PinosListener global_added;
 | 
			
		||||
  PinosListener global_removed;
 | 
			
		||||
  PinosListener port_added;
 | 
			
		||||
  PinosListener port_removed;
 | 
			
		||||
  PinosListener port_unlinked;
 | 
			
		||||
  PinosListener node_state_changed;
 | 
			
		||||
  PinosListener link_state_changed;
 | 
			
		||||
} ModuleImpl;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -184,22 +182,6 @@ on_node_created (PinosNode       *node,
 | 
			
		|||
    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
 | 
			
		||||
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_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_removed, &impl->port_removed, on_port_removed);
 | 
			
		||||
  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);
 | 
			
		||||
 | 
			
		||||
  impl->global = pinos_core_add_global (core,
 | 
			
		||||
                                        core->uri.module,
 | 
			
		||||
                                        impl);
 | 
			
		||||
  return impl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -286,7 +264,6 @@ module_destroy (ModuleImpl *impl)
 | 
			
		|||
 | 
			
		||||
  pinos_signal_remove (&impl->global_added);
 | 
			
		||||
  pinos_signal_remove (&impl->global_removed);
 | 
			
		||||
  pinos_signal_remove (&impl->node_state_changed);
 | 
			
		||||
  pinos_signal_remove (&impl->port_added);
 | 
			
		||||
  pinos_signal_remove (&impl->port_removed);
 | 
			
		||||
  pinos_signal_remove (&impl->port_unlinked);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,7 +53,6 @@
 | 
			
		|||
typedef struct {
 | 
			
		||||
  PinosCore   *core;
 | 
			
		||||
  SpaList      link;
 | 
			
		||||
  PinosGlobal *global;
 | 
			
		||||
 | 
			
		||||
  PinosProperties *properties;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -164,6 +163,7 @@ find_object (PinosProtocolDBus *impl,
 | 
			
		|||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
struct _PinosProperties {
 | 
			
		||||
  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));
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
pinos_properties_init_builder (PinosProperties *properties,
 | 
			
		||||
                               GVariantBuilder *builder)
 | 
			
		||||
{
 | 
			
		||||
  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 *
 | 
			
		||||
| 
						 | 
				
			
			@ -201,10 +202,10 @@ pinos_properties_from_variant (GVariant *variant)
 | 
			
		|||
  props = pinos_properties_new (NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  g_variant_iter_init (&iter, variant);
 | 
			
		||||
  while (g_variant_iter_loop (&iter, "{sv}", &key, &value))
 | 
			
		||||
    g_hash_table_replace (props->hashtable,
 | 
			
		||||
                          g_strdup (key),
 | 
			
		||||
                          g_variant_dup_string (value, NULL));
 | 
			
		||||
//  while (g_variant_iter_loop (&iter, "{sv}", &key, &value))
 | 
			
		||||
    //g_hash_table_replace (props->hashtable,
 | 
			
		||||
    //                      g_strdup (key),
 | 
			
		||||
    //                      g_variant_dup_string (value, NULL));
 | 
			
		||||
 | 
			
		||||
  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->global = pinos_core_add_global (core,
 | 
			
		||||
                                        core->uri.module,
 | 
			
		||||
                                        impl);
 | 
			
		||||
  return impl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,220 +64,33 @@ typedef struct {
 | 
			
		|||
typedef struct {
 | 
			
		||||
  PinosCore   *core;
 | 
			
		||||
  SpaList      link;
 | 
			
		||||
  PinosGlobal *global;
 | 
			
		||||
 | 
			
		||||
  PinosProperties *properties;
 | 
			
		||||
 | 
			
		||||
  SpaList socket_list;
 | 
			
		||||
 | 
			
		||||
  SpaList client_list;
 | 
			
		||||
  SpaList object_list;
 | 
			
		||||
 | 
			
		||||
  PinosListener global_added;
 | 
			
		||||
  PinosListener global_removed;
 | 
			
		||||
  PinosListener node_state_changed;
 | 
			
		||||
} PinosProtocolNative;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  PinosProtocolNative *impl;
 | 
			
		||||
  SpaList              link;
 | 
			
		||||
  PinosGlobal         *global;
 | 
			
		||||
  PinosDestroy         destroy;
 | 
			
		||||
} PinosProtocolNativeObject;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  PinosProtocolNativeObject parent;
 | 
			
		||||
  SpaList                   link;
 | 
			
		||||
} PinosProtocolNativeServer;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  PinosProtocolNativeObject parent;
 | 
			
		||||
  SpaList                   link;
 | 
			
		||||
  int                       fd;
 | 
			
		||||
  struct ucred              ucred;
 | 
			
		||||
  SpaSource                *source;
 | 
			
		||||
  PinosConnection          *connection;
 | 
			
		||||
  PinosResource            *core_resource;
 | 
			
		||||
  PinosClient         *client;
 | 
			
		||||
  int                  fd;
 | 
			
		||||
  struct ucred         ucred;
 | 
			
		||||
  SpaSource           *source;
 | 
			
		||||
  PinosConnection     *connection;
 | 
			
		||||
} 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
 | 
			
		||||
client_destroy (PinosProtocolNativeClient *this)
 | 
			
		||||
{
 | 
			
		||||
  pinos_client_destroy (this->client);
 | 
			
		||||
  spa_list_remove (&this->link);
 | 
			
		||||
  if (this->source)
 | 
			
		||||
    pinos_loop_destroy_source (this->parent.impl->core->main_loop->loop,
 | 
			
		||||
                               this->source);
 | 
			
		||||
  pinos_loop_destroy_source (this->impl->core->main_loop->loop,
 | 
			
		||||
                             this->source);
 | 
			
		||||
  pinos_connection_destroy (this->connection);
 | 
			
		||||
  close (this->fd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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, ®istry_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;
 | 
			
		||||
  free (this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static SpaResult
 | 
			
		||||
| 
						 | 
				
			
			@ -290,7 +103,8 @@ client_send_func (void             *object,
 | 
			
		|||
{
 | 
			
		||||
  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,
 | 
			
		||||
                                id,
 | 
			
		||||
| 
						 | 
				
			
			@ -313,14 +127,11 @@ connection_data (SpaSource *source,
 | 
			
		|||
  PinosMessageType type;
 | 
			
		||||
  uint32_t id;
 | 
			
		||||
  size_t size;
 | 
			
		||||
  PinosClient *c = client->parent.global->object;
 | 
			
		||||
  PinosClient *c = client->client;
 | 
			
		||||
 | 
			
		||||
  if (mask & (SPA_IO_ERR | SPA_IO_HUP)) {
 | 
			
		||||
    pinos_log_debug ("protocol-native %p: got connection error", client->parent.impl);
 | 
			
		||||
    pinos_loop_destroy_source (client->parent.impl->core->main_loop->loop,
 | 
			
		||||
                               client->source);
 | 
			
		||||
    client->source = NULL;
 | 
			
		||||
    pinos_client_destroy (client->parent.global->object);
 | 
			
		||||
    pinos_log_debug ("protocol-native %p: got connection error", client->impl);
 | 
			
		||||
    client_destroy (client);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -328,16 +139,16 @@ connection_data (SpaSource *source,
 | 
			
		|||
    PinosResource *resource;
 | 
			
		||||
    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)) {
 | 
			
		||||
      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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    resource = pinos_map_lookup (&c->objects, id);
 | 
			
		||||
    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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -353,27 +164,14 @@ client_new (PinosProtocolNative *impl,
 | 
			
		|||
            int                  fd)
 | 
			
		||||
{
 | 
			
		||||
  PinosProtocolNativeClient *this;
 | 
			
		||||
  PinosClient *client;
 | 
			
		||||
  socklen_t len;
 | 
			
		||||
 | 
			
		||||
  client = pinos_client_new (impl->core, NULL);
 | 
			
		||||
 | 
			
		||||
  if ((this = (PinosProtocolNativeClient *) find_object (impl, client)) == NULL) {
 | 
			
		||||
    close (fd);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  this = calloc (1, sizeof (PinosProtocolNativeClient));
 | 
			
		||||
  this->impl = impl;
 | 
			
		||||
  len = sizeof (this->ucred);
 | 
			
		||||
  if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &this->ucred, &len) < 0) {
 | 
			
		||||
    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->source = pinos_loop_add_io (impl->core->main_loop->loop,
 | 
			
		||||
                                    this->fd,
 | 
			
		||||
| 
						 | 
				
			
			@ -381,75 +179,23 @@ client_new (PinosProtocolNative *impl,
 | 
			
		|||
                                    false,
 | 
			
		||||
                                    connection_data,
 | 
			
		||||
                                    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);
 | 
			
		||||
 | 
			
		||||
  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;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 *
 | 
			
		||||
create_socket (void)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -628,7 +374,6 @@ pinos_protocol_native_new (PinosCore       *core,
 | 
			
		|||
 | 
			
		||||
  spa_list_init (&impl->socket_list);
 | 
			
		||||
  spa_list_init (&impl->client_list);
 | 
			
		||||
  spa_list_init (&impl->object_list);
 | 
			
		||||
 | 
			
		||||
  if (!init_socket_name (s, name))
 | 
			
		||||
    goto error;
 | 
			
		||||
| 
						 | 
				
			
			@ -639,12 +384,6 @@ pinos_protocol_native_new (PinosCore       *core,
 | 
			
		|||
  if (!add_socket (impl, s))
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
error:
 | 
			
		||||
| 
						 | 
				
			
			@ -666,10 +405,6 @@ pinos_protocol_native_destroy (PinosProtocolNative *impl)
 | 
			
		|||
  spa_list_for_each_safe (object, tmp, &impl->object_list, link)
 | 
			
		||||
    object_destroy (object);
 | 
			
		||||
 | 
			
		||||
  pinos_signal_remove (&impl->global_added);
 | 
			
		||||
  pinos_signal_remove (&impl->global_removed);
 | 
			
		||||
  pinos_signal_remove (&impl->node_state_changed);
 | 
			
		||||
 | 
			
		||||
  free (impl);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,7 +29,6 @@
 | 
			
		|||
typedef struct {
 | 
			
		||||
  PinosCore       *core;
 | 
			
		||||
  PinosProperties *properties;
 | 
			
		||||
  PinosGlobal     *global;
 | 
			
		||||
 | 
			
		||||
  PinosListener global_added;
 | 
			
		||||
  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_changed, &impl->node_state_changed, on_node_state_changed);
 | 
			
		||||
 | 
			
		||||
  impl->global = pinos_core_add_global (core,
 | 
			
		||||
                                        core->uri.module,
 | 
			
		||||
                                        impl);
 | 
			
		||||
  return impl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,6 +21,8 @@
 | 
			
		|||
#include <getopt.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
 | 
			
		||||
#include <spa/lib/props.h>
 | 
			
		||||
 | 
			
		||||
#include <pinos/client/utils.h>
 | 
			
		||||
#include <pinos/server/core.h>
 | 
			
		||||
#include <pinos/server/module.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -28,6 +30,43 @@
 | 
			
		|||
#include "spa-monitor.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
 | 
			
		||||
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",
 | 
			
		||||
                       "audiotestsrc",
 | 
			
		||||
                       "audiotestsrc",
 | 
			
		||||
                       NULL,
 | 
			
		||||
                       NULL);
 | 
			
		||||
  pinos_spa_node_load (module->core,
 | 
			
		||||
                       "build/spa/plugins/videotestsrc/libspa-videotestsrc.so",
 | 
			
		||||
                       "videotestsrc",
 | 
			
		||||
                       "videotestsrc",
 | 
			
		||||
                       video_props);
 | 
			
		||||
                       video_props,
 | 
			
		||||
                       setup_video_node);
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,7 +37,8 @@ pinos_spa_node_load (PinosCore  *core,
 | 
			
		|||
                     const char *lib,
 | 
			
		||||
                     const char *factory_name,
 | 
			
		||||
                     const char *name,
 | 
			
		||||
                     PinosProperties *properties)
 | 
			
		||||
                     PinosProperties *properties,
 | 
			
		||||
                     SetupNode setup_func)
 | 
			
		||||
{
 | 
			
		||||
  PinosSpaNode *this;
 | 
			
		||||
  PinosSpaNodeImpl *impl;
 | 
			
		||||
| 
						 | 
				
			
			@ -97,6 +98,13 @@ pinos_spa_node_load (PinosCore  *core,
 | 
			
		|||
  impl->core = core;
 | 
			
		||||
  impl->hnd = hnd;
 | 
			
		||||
  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,
 | 
			
		||||
                               name,
 | 
			
		||||
                               spa_node,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,7 @@
 | 
			
		|||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef struct _PinosSpaNode PinosSpaNode;
 | 
			
		||||
 | 
			
		||||
struct _PinosSpaNode {
 | 
			
		||||
| 
						 | 
				
			
			@ -38,11 +39,15 @@ struct _PinosSpaNode {
 | 
			
		|||
                                 PinosSpaNode  *node));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef SpaResult (*SetupNode) (SpaNode         *spa_node,
 | 
			
		||||
                                PinosProperties *pinos_props);
 | 
			
		||||
 | 
			
		||||
PinosSpaNode *    pinos_spa_node_load      (PinosCore       *core,
 | 
			
		||||
                                            const char      *lib,
 | 
			
		||||
                                            const char      *factory_name,
 | 
			
		||||
                                            const char      *name,
 | 
			
		||||
                                            PinosProperties *properties);
 | 
			
		||||
                                            PinosProperties *properties,
 | 
			
		||||
                                            SetupNode       setup_func);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,6 +28,57 @@ typedef struct
 | 
			
		|||
  PinosClient this;
 | 
			
		||||
} 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:
 | 
			
		||||
 * @daemon: a #PinosDaemon
 | 
			
		||||
| 
						 | 
				
			
			@ -58,7 +109,9 @@ pinos_client_new (PinosCore       *core,
 | 
			
		|||
 | 
			
		||||
  this->global = pinos_core_add_global (core,
 | 
			
		||||
                                        core->uri.client,
 | 
			
		||||
                                        this);
 | 
			
		||||
                                        0,
 | 
			
		||||
                                        this,
 | 
			
		||||
                                        client_bind_func);
 | 
			
		||||
 | 
			
		||||
  return this;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,9 +24,6 @@
 | 
			
		|||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define PINOS_CLIENT_URI                            "http://pinos.org/ns/client"
 | 
			
		||||
#define PINOS_CLIENT_PREFIX                         PINOS_CLIENT_URI "#"
 | 
			
		||||
 | 
			
		||||
typedef struct _PinosClient PinosClient;
 | 
			
		||||
 | 
			
		||||
#include <pinos/server/core.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -44,6 +41,8 @@ struct _PinosClient {
 | 
			
		|||
 | 
			
		||||
  PinosProperties *properties;
 | 
			
		||||
 | 
			
		||||
  PinosResource *core_resource;
 | 
			
		||||
 | 
			
		||||
  PinosMap objects;
 | 
			
		||||
 | 
			
		||||
  PinosSendFunc   send_func;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,7 @@
 | 
			
		|||
#include <pinos/client/pinos.h>
 | 
			
		||||
#include <pinos/server/core.h>
 | 
			
		||||
#include <pinos/server/data-loop.h>
 | 
			
		||||
#include <pinos/server/client-node.h>
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  PinosCore  this;
 | 
			
		||||
| 
						 | 
				
			
			@ -28,6 +29,179 @@ typedef struct {
 | 
			
		|||
 | 
			
		||||
} 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, ®istry_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 *
 | 
			
		||||
pinos_core_new (PinosMainLoop *main_loop)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -76,7 +250,9 @@ pinos_core_new (PinosMainLoop *main_loop)
 | 
			
		|||
 | 
			
		||||
  this->global = pinos_core_add_global (this,
 | 
			
		||||
                                        this->uri.core,
 | 
			
		||||
                                        this);
 | 
			
		||||
                                        0,
 | 
			
		||||
                                        this,
 | 
			
		||||
                                        core_bind_func);
 | 
			
		||||
 | 
			
		||||
  return this;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -96,14 +272,18 @@ pinos_core_destroy (PinosCore *core)
 | 
			
		|||
PinosGlobal *
 | 
			
		||||
pinos_core_add_global (PinosCore           *core,
 | 
			
		||||
                       uint32_t             type,
 | 
			
		||||
                       void                *object)
 | 
			
		||||
                       uint32_t             version,
 | 
			
		||||
                       void                *object,
 | 
			
		||||
                       PinosBindFunc        bind)
 | 
			
		||||
{
 | 
			
		||||
  PinosGlobal *global;
 | 
			
		||||
 | 
			
		||||
  global = calloc (1, sizeof (PinosGlobal));
 | 
			
		||||
  global->core = core;
 | 
			
		||||
  global->type = type;
 | 
			
		||||
  global->version = version;
 | 
			
		||||
  global->object = object;
 | 
			
		||||
  global->bind = bind;
 | 
			
		||||
 | 
			
		||||
  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);
 | 
			
		||||
 | 
			
		||||
  spa_list_for_each (n, &core->node_list, link) {
 | 
			
		||||
    if (n->global == NULL)
 | 
			
		||||
      continue;
 | 
			
		||||
 | 
			
		||||
    pinos_log_debug ("node id \"%d\"", n->global->id);
 | 
			
		||||
 | 
			
		||||
    if (have_id) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,26 +27,31 @@ extern "C" {
 | 
			
		|||
typedef struct _PinosCore PinosCore;
 | 
			
		||||
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 <pinos/client/uri.h>
 | 
			
		||||
 | 
			
		||||
#include <pinos/server/main-loop.h>
 | 
			
		||||
#include <pinos/server/data-loop.h>
 | 
			
		||||
#include <pinos/server/uri.h>
 | 
			
		||||
#include <pinos/server/node.h>
 | 
			
		||||
#include <pinos/server/link.h>
 | 
			
		||||
#include <pinos/server/node-factory.h>
 | 
			
		||||
 | 
			
		||||
typedef void (*PinosBindFunc)  (PinosGlobal   *global,
 | 
			
		||||
                                PinosClient   *client,
 | 
			
		||||
                                uint32_t       version,
 | 
			
		||||
                                uint32_t       id);
 | 
			
		||||
 | 
			
		||||
struct _PinosGlobal {
 | 
			
		||||
  PinosCore *core;
 | 
			
		||||
  SpaList    link;
 | 
			
		||||
  uint32_t   id;
 | 
			
		||||
  uint32_t   type;
 | 
			
		||||
  uint32_t   version;
 | 
			
		||||
  void      *object;
 | 
			
		||||
 | 
			
		||||
  PinosBindFunc bind;
 | 
			
		||||
 | 
			
		||||
  PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
 | 
			
		||||
                                 PinosGlobal   *global));
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -116,7 +121,9 @@ void            pinos_core_destroy       (PinosCore     *core);
 | 
			
		|||
 | 
			
		||||
PinosGlobal *   pinos_core_add_global    (PinosCore           *core,
 | 
			
		||||
                                          uint32_t             type,
 | 
			
		||||
                                          void                *object);
 | 
			
		||||
                                          uint32_t             version,
 | 
			
		||||
                                          void                *object,
 | 
			
		||||
                                          PinosBindFunc        bind);
 | 
			
		||||
void            pinos_global_destroy     (PinosGlobal         *global);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -668,6 +668,39 @@ pinos_pinos_link_deactivate (PinosLink *this)
 | 
			
		|||
  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 *
 | 
			
		||||
pinos_link_new (PinosCore       *core,
 | 
			
		||||
                PinosPort       *output,
 | 
			
		||||
| 
						 | 
				
			
			@ -717,7 +750,9 @@ pinos_link_new (PinosCore       *core,
 | 
			
		|||
 | 
			
		||||
  this->global = pinos_core_add_global (core,
 | 
			
		||||
                                        core->uri.link,
 | 
			
		||||
                                        this);
 | 
			
		||||
                                        0,
 | 
			
		||||
                                        this,
 | 
			
		||||
                                        link_bind_func);
 | 
			
		||||
  return this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,9 +26,6 @@ extern "C" {
 | 
			
		|||
 | 
			
		||||
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 <pinos/client/mem.h>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,6 @@ pinoscore_headers = [
 | 
			
		|||
  'node-factory.h',
 | 
			
		||||
  'port.h',
 | 
			
		||||
  'resource.h',
 | 
			
		||||
  'uri.h',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
pinoscore_sources = [
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +26,6 @@ pinoscore_sources = [
 | 
			
		|||
  'node-factory.c',
 | 
			
		||||
  'port.c',
 | 
			
		||||
  'resource.c',
 | 
			
		||||
  'uri.c',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
libpinoscore_c_args = [
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -90,6 +90,59 @@ find_module (const char * path, const char *name)
 | 
			
		|||
  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:
 | 
			
		||||
 * @core: a #PinosCore
 | 
			
		||||
| 
						 | 
				
			
			@ -140,7 +193,6 @@ pinos_module_load (PinosCore    *core,
 | 
			
		|||
  pinos_log_debug ("trying to load module: %s (%s)", name, filename);
 | 
			
		||||
 | 
			
		||||
  hnd = dlopen (filename, RTLD_NOW | RTLD_LOCAL);
 | 
			
		||||
  free (filename);
 | 
			
		||||
 | 
			
		||||
  if (hnd == NULL)
 | 
			
		||||
    goto open_failed;
 | 
			
		||||
| 
						 | 
				
			
			@ -152,7 +204,9 @@ pinos_module_load (PinosCore    *core,
 | 
			
		|||
  impl->hnd = hnd;
 | 
			
		||||
 | 
			
		||||
  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;
 | 
			
		||||
 | 
			
		||||
  if (!init_func (this, (char *) args))
 | 
			
		||||
| 
						 | 
				
			
			@ -160,6 +214,12 @@ pinos_module_load (PinosCore    *core,
 | 
			
		|||
 | 
			
		||||
  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;
 | 
			
		||||
 | 
			
		||||
not_found:
 | 
			
		||||
| 
						 | 
				
			
			@ -170,12 +230,14 @@ not_found:
 | 
			
		|||
open_failed:
 | 
			
		||||
  {
 | 
			
		||||
    asprintf (err, "Failed to open module: %s", dlerror ());
 | 
			
		||||
    free (filename);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
no_pinos_module:
 | 
			
		||||
  {
 | 
			
		||||
    asprintf (err, "\"%s\" is not a pinos module", name);
 | 
			
		||||
    dlclose (hnd);
 | 
			
		||||
    free (filename);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
init_failed:
 | 
			
		||||
| 
						 | 
				
			
			@ -193,7 +255,12 @@ pinos_module_destroy (PinosModule *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);
 | 
			
		||||
  free (impl);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,16 +27,16 @@ extern "C" {
 | 
			
		|||
 | 
			
		||||
#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;
 | 
			
		||||
 | 
			
		||||
struct _PinosModule {
 | 
			
		||||
  PinosCore *core;
 | 
			
		||||
  SpaList    link;
 | 
			
		||||
  PinosGlobal *global;
 | 
			
		||||
 | 
			
		||||
  char *name;
 | 
			
		||||
  char *filename;
 | 
			
		||||
  char *args;
 | 
			
		||||
 | 
			
		||||
  PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
 | 
			
		||||
                                 PinosModule   *module));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
init_complete (PinosNode *this)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -391,7 +453,15 @@ init_complete (PinosNode *this)
 | 
			
		|||
  pinos_log_debug ("node %p: init completed", this);
 | 
			
		||||
  impl->async_init = false;
 | 
			
		||||
 | 
			
		||||
  spa_list_insert (this->core->node_list.prev, &this->link);
 | 
			
		||||
 | 
			
		||||
  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
 | 
			
		||||
| 
						 | 
				
			
			@ -424,6 +494,8 @@ pinos_node_new (PinosCore       *core,
 | 
			
		|||
  this->clock = clock;
 | 
			
		||||
  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)
 | 
			
		||||
    pinos_log_warn ("node %p: error setting callback", this);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -459,11 +531,7 @@ pinos_node_new (PinosCore       *core,
 | 
			
		|||
                           (PinosDeferFunc) init_complete,
 | 
			
		||||
                           NULL);
 | 
			
		||||
  }
 | 
			
		||||
  spa_list_insert (core->node_list.prev, &this->link);
 | 
			
		||||
 | 
			
		||||
  this->global = pinos_core_add_global (core,
 | 
			
		||||
                                        core->uri.node,
 | 
			
		||||
                                        this);
 | 
			
		||||
  return this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -724,6 +792,10 @@ pinos_node_update_state (PinosNode      *node,
 | 
			
		|||
 | 
			
		||||
  old = node->state;
 | 
			
		||||
  if (old != state) {
 | 
			
		||||
    PinosMessageNodeInfo m;
 | 
			
		||||
    PinosNodeInfo info;
 | 
			
		||||
    PinosResource *resource;
 | 
			
		||||
 | 
			
		||||
    pinos_log_debug ("node %p: update state from %s -> %s", node,
 | 
			
		||||
        pinos_node_state_as_string (old),
 | 
			
		||||
        pinos_node_state_as_string (state));
 | 
			
		||||
| 
						 | 
				
			
			@ -732,6 +804,20 @@ pinos_node_update_state (PinosNode      *node,
 | 
			
		|||
      free (node->error);
 | 
			
		||||
    node->error = error;
 | 
			
		||||
    node->state = 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);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,6 +62,8 @@ struct _PinosNode {
 | 
			
		|||
  bool live;
 | 
			
		||||
  SpaClock *clock;
 | 
			
		||||
 | 
			
		||||
  SpaList resource_list;
 | 
			
		||||
 | 
			
		||||
  SpaList input_ports;
 | 
			
		||||
  SpaList output_ports;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,14 +82,14 @@ pinos_resource_destroy (PinosResource *resource)
 | 
			
		|||
 | 
			
		||||
SpaResult
 | 
			
		||||
pinos_resource_send_message (PinosResource     *resource,
 | 
			
		||||
                             PinosMessageType   type,
 | 
			
		||||
                             uint32_t           opcode,
 | 
			
		||||
                             void              *message,
 | 
			
		||||
                             bool               flush)
 | 
			
		||||
{
 | 
			
		||||
  if (resource->send_func)
 | 
			
		||||
    return resource->send_func (resource,
 | 
			
		||||
                                resource->id,
 | 
			
		||||
                                type,
 | 
			
		||||
                                opcode,
 | 
			
		||||
                                message,
 | 
			
		||||
                                flush,
 | 
			
		||||
                                resource->send_data);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,13 +35,13 @@ typedef void  (*PinosDestroy)  (void *object);
 | 
			
		|||
 | 
			
		||||
typedef SpaResult (*PinosSendFunc) (void             *object,
 | 
			
		||||
                                    uint32_t          id,
 | 
			
		||||
                                    PinosMessageType  type,
 | 
			
		||||
                                    uint32_t          opcode,
 | 
			
		||||
                                    void             *message,
 | 
			
		||||
                                    bool              flush,
 | 
			
		||||
                                    void             *data);
 | 
			
		||||
 | 
			
		||||
typedef SpaResult (*PinosDispatchFunc) (void             *object,
 | 
			
		||||
                                        PinosMessageType  type,
 | 
			
		||||
                                        uint32_t          opcode,
 | 
			
		||||
                                        void             *message,
 | 
			
		||||
                                        void             *data);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -73,7 +73,7 @@ PinosResource * pinos_resource_new                (PinosClient  *client,
 | 
			
		|||
SpaResult       pinos_resource_destroy            (PinosResource *resource);
 | 
			
		||||
 | 
			
		||||
SpaResult       pinos_resource_send_message       (PinosResource     *resource,
 | 
			
		||||
                                                   PinosMessageType   type,
 | 
			
		||||
                                                   uint32_t           opcode,
 | 
			
		||||
                                                   void              *message,
 | 
			
		||||
                                                   bool               flush);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,17 +31,16 @@ typedef struct {
 | 
			
		|||
} Data;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
print_properties (PinosProperties *props, char mark)
 | 
			
		||||
print_properties (SpaDict *props, char mark)
 | 
			
		||||
{
 | 
			
		||||
  void *state = NULL;
 | 
			
		||||
  const char *key;
 | 
			
		||||
  SpaDictItem *item;
 | 
			
		||||
 | 
			
		||||
  if (props == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  printf ("%c\tproperties:\n", mark);
 | 
			
		||||
  while ((key = pinos_properties_iterate (props, &state))) {
 | 
			
		||||
    printf ("%c\t\t%s = \"%s\"\n", mark, key, pinos_properties_get (props, key));
 | 
			
		||||
  spa_dict_for_each (item, props) {
 | 
			
		||||
    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)))) ? '*' : ' ')
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
  if (info == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  printf ("\tid: %u\n", info->id);
 | 
			
		||||
  printf ("\ttype: %s\n", PINOS_CORE_URI);
 | 
			
		||||
  if (data->print_all) {
 | 
			
		||||
    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\tversion: \"%s\"\n", MARK_CHANGE (2), info->version);
 | 
			
		||||
    printf ("%c\tname: \"%s\"\n", MARK_CHANGE (3), info->name);
 | 
			
		||||
    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
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
  if (info == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  printf ("\tid: %u\n", info->id);
 | 
			
		||||
  printf ("\ttype: %s\n", PINOS_CLIENT_URI);
 | 
			
		||||
  if (data->print_all) {
 | 
			
		||||
    print_properties (info->properties, MARK_CHANGE (0));
 | 
			
		||||
    print_properties (info->props, MARK_CHANGE (0));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
  if (info == NULL) {
 | 
			
		||||
    if (res != SPA_RESULT_ENUM_END)
 | 
			
		||||
      printf ("\tError introspecting node: %d\n", res);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  printf ("\tid: %u\n", info->id);
 | 
			
		||||
  printf ("\ttype: %s\n", PINOS_NODE_URI);
 | 
			
		||||
  if (data->print_all) {
 | 
			
		||||
    printf ("%c\tname: \"%s\"\n", MARK_CHANGE (0), info->name);
 | 
			
		||||
    print_properties (info->properties, MARK_CHANGE (1));
 | 
			
		||||
    printf ("%c\tstate: \"%s\"\n", MARK_CHANGE (2), pinos_node_state_as_string (info->state));
 | 
			
		||||
    printf ("%c\tstate: \"%s\"\n", MARK_CHANGE (1), pinos_node_state_as_string (info->state));
 | 
			
		||||
    print_properties (info->props, MARK_CHANGE (2));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
  if (info == NULL) {
 | 
			
		||||
    if (res != SPA_RESULT_ENUM_END)
 | 
			
		||||
      printf ("\tError introspecting module: %d\n", res);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  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) {
 | 
			
		||||
    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);
 | 
			
		||||
| 
						 | 
				
			
			@ -108,49 +165,66 @@ dump_link_info (PinosContext *c, const PinosLinkInfo *info, void * user_data)
 | 
			
		|||
 | 
			
		||||
static void
 | 
			
		||||
dump_object (PinosContext           *context,
 | 
			
		||||
             uint32_t                type,
 | 
			
		||||
             uint32_t                id,
 | 
			
		||||
             PinosSubscriptionFlags  flags,
 | 
			
		||||
             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
 | 
			
		||||
subscription_cb (PinosContext           *context,
 | 
			
		||||
                 PinosSubscriptionFlags  flags,
 | 
			
		||||
                 PinosSubscriptionEvent  type,
 | 
			
		||||
                 PinosSubscriptionEvent  event,
 | 
			
		||||
                 uint32_t                type,
 | 
			
		||||
                 uint32_t                id,
 | 
			
		||||
                 void                   *data)
 | 
			
		||||
{
 | 
			
		||||
  DumpData dd;
 | 
			
		||||
 | 
			
		||||
  switch (type) {
 | 
			
		||||
  switch (event) {
 | 
			
		||||
    case PINOS_SUBSCRIPTION_EVENT_NEW:
 | 
			
		||||
      printf ("added:\n");
 | 
			
		||||
      dd.print_mark = false;
 | 
			
		||||
      dd.print_all = true;
 | 
			
		||||
      dump_object (context, id, flags, &dd);
 | 
			
		||||
      dump_object (context, type, id, &dd);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PINOS_SUBSCRIPTION_EVENT_CHANGE:
 | 
			
		||||
      printf ("changed:\n");
 | 
			
		||||
      dd.print_mark = true;
 | 
			
		||||
      dd.print_all = true;
 | 
			
		||||
      dump_object (context, id, flags, &dd);
 | 
			
		||||
      dump_object (context, type, id, &dd);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PINOS_SUBSCRIPTION_EVENT_REMOVE:
 | 
			
		||||
      printf ("removed:\n");
 | 
			
		||||
      dd.print_mark = false;
 | 
			
		||||
      dd.print_all = false;
 | 
			
		||||
      dump_object (context, id, flags, &dd);
 | 
			
		||||
      dump_object (context, type, id, &dd);
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -189,7 +263,6 @@ main (int argc, char *argv[])
 | 
			
		|||
                    on_state_changed);
 | 
			
		||||
 | 
			
		||||
  pinos_context_subscribe (data.context,
 | 
			
		||||
                           PINOS_SUBSCRIPTION_FLAGS_ALL,
 | 
			
		||||
                           subscription_cb,
 | 
			
		||||
                           &data);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,6 +65,7 @@ typedef enum {
 | 
			
		|||
  SPA_RESULT_INVALID_BUFFER_ID         = -28,
 | 
			
		||||
  SPA_RESULT_WRONG_STATE               = -29,
 | 
			
		||||
  SPA_RESULT_ASYNC_BUSY                = -30,
 | 
			
		||||
  SPA_RESULT_INVALID_OBJECT_ID         = -31,
 | 
			
		||||
} SpaResult;
 | 
			
		||||
 | 
			
		||||
#define SPA_ASYNC_MASK                  (3 << 30)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue