mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	Use interfaces
Add interfaces and events on objects. Use this to communicate with the objects and transparently convert/marshall to network in the protocols.
This commit is contained in:
		
							parent
							
								
									9b7debbfd3
								
							
						
					
					
						commit
						e0813b679d
					
				
					 16 changed files with 1307 additions and 822 deletions
				
			
		| 
						 | 
					@ -312,7 +312,7 @@ connection_parse_use_buffers (PinosConnection *conn, PinosMessageUseBuffers *cmd
 | 
				
			||||||
  p = conn->in.data;
 | 
					  p = conn->in.data;
 | 
				
			||||||
  memcpy (cmd, p, sizeof (PinosMessageUseBuffers));
 | 
					  memcpy (cmd, p, sizeof (PinosMessageUseBuffers));
 | 
				
			||||||
  if (cmd->buffers)
 | 
					  if (cmd->buffers)
 | 
				
			||||||
    cmd->buffers = SPA_MEMBER (p, SPA_PTR_TO_INT (cmd->buffers), PinosMessageBuffer);
 | 
					    cmd->buffers = SPA_MEMBER (p, SPA_PTR_TO_INT (cmd->buffers), PinosClientNodeBuffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (i = 0; i < cmd->n_buffers; i++) {
 | 
					  for (i = 0; i < cmd->n_buffers; i++) {
 | 
				
			||||||
    if (cmd->buffers[i].buffer)
 | 
					    if (cmd->buffers[i].buffer)
 | 
				
			||||||
| 
						 | 
					@ -886,12 +886,12 @@ connection_add_use_buffers (PinosConnection *conn, uint32_t dest_id, PinosMessag
 | 
				
			||||||
  size_t len;
 | 
					  size_t len;
 | 
				
			||||||
  int i;
 | 
					  int i;
 | 
				
			||||||
  PinosMessageUseBuffers *d;
 | 
					  PinosMessageUseBuffers *d;
 | 
				
			||||||
  PinosMessageBuffer *b;
 | 
					  PinosClientNodeBuffer *b;
 | 
				
			||||||
  void *p;
 | 
					  void *p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* calculate length */
 | 
					  /* calculate length */
 | 
				
			||||||
  len = sizeof (PinosMessageUseBuffers);
 | 
					  len = sizeof (PinosMessageUseBuffers);
 | 
				
			||||||
  len += ub->n_buffers * sizeof (PinosMessageBuffer);
 | 
					  len += ub->n_buffers * sizeof (PinosClientNodeBuffer);
 | 
				
			||||||
  for (i = 0; i < ub->n_buffers; i++)
 | 
					  for (i = 0; i < ub->n_buffers; i++)
 | 
				
			||||||
    len += pinos_serialize_buffer_get_size (ub->buffers[i].buffer);
 | 
					    len += pinos_serialize_buffer_get_size (ub->buffers[i].buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -899,7 +899,7 @@ connection_add_use_buffers (PinosConnection *conn, uint32_t dest_id, PinosMessag
 | 
				
			||||||
  memcpy (d, ub, sizeof (PinosMessageUseBuffers));
 | 
					  memcpy (d, ub, sizeof (PinosMessageUseBuffers));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  b = SPA_MEMBER (d, sizeof (PinosMessageUseBuffers), void);
 | 
					  b = SPA_MEMBER (d, sizeof (PinosMessageUseBuffers), void);
 | 
				
			||||||
  p = SPA_MEMBER (b, ub->n_buffers * sizeof (PinosMessageBuffer), void);
 | 
					  p = SPA_MEMBER (b, ub->n_buffers * sizeof (PinosClientNodeBuffer), void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (d->n_buffers)
 | 
					  if (d->n_buffers)
 | 
				
			||||||
    d->buffers = SPA_INT_TO_PTR (SPA_PTRDIFF (b, d));
 | 
					    d->buffers = SPA_INT_TO_PTR (SPA_PTRDIFF (b, d));
 | 
				
			||||||
| 
						 | 
					@ -907,7 +907,7 @@ connection_add_use_buffers (PinosConnection *conn, uint32_t dest_id, PinosMessag
 | 
				
			||||||
    d->buffers = 0;
 | 
					    d->buffers = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (i = 0; i < ub->n_buffers; i++) {
 | 
					  for (i = 0; i < ub->n_buffers; i++) {
 | 
				
			||||||
    memcpy (&b[i], &ub->buffers[i], sizeof (PinosMessageBuffer));
 | 
					    memcpy (&b[i], &ub->buffers[i], sizeof (PinosClientNodeBuffer));
 | 
				
			||||||
    len = pinos_serialize_buffer_serialize (p, b[i].buffer);
 | 
					    len = pinos_serialize_buffer_serialize (p, b[i].buffer);
 | 
				
			||||||
    b[i].buffer = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
 | 
					    b[i].buffer = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
 | 
				
			||||||
    p += len;
 | 
					    p += len;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,6 +30,8 @@ extern "C" {
 | 
				
			||||||
#include <spa/port.h>
 | 
					#include <spa/port.h>
 | 
				
			||||||
#include <spa/node.h>
 | 
					#include <spa/node.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <pinos/client/interfaces.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct _PinosConnection PinosConnection;
 | 
					typedef struct _PinosConnection PinosConnection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum {
 | 
					typedef enum {
 | 
				
			||||||
| 
						 | 
					@ -253,7 +255,7 @@ typedef struct {
 | 
				
			||||||
  SpaDirection        direction;
 | 
					  SpaDirection        direction;
 | 
				
			||||||
  uint32_t            port_id;
 | 
					  uint32_t            port_id;
 | 
				
			||||||
  SpaPortFormatFlags  flags;
 | 
					  SpaPortFormatFlags  flags;
 | 
				
			||||||
  SpaFormat          *format;
 | 
					  const SpaFormat    *format;
 | 
				
			||||||
} PinosMessageSetFormat;
 | 
					} PinosMessageSetFormat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* PINOS_MESSAGE_SET_PROPERTY */
 | 
					/* PINOS_MESSAGE_SET_PROPERTY */
 | 
				
			||||||
| 
						 | 
					@ -295,20 +297,13 @@ typedef struct {
 | 
				
			||||||
  size_t       size;
 | 
					  size_t       size;
 | 
				
			||||||
} PinosMessageAddMem;
 | 
					} PinosMessageAddMem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					 | 
				
			||||||
  SpaBuffer  *buffer;
 | 
					 | 
				
			||||||
  uint32_t    mem_id;
 | 
					 | 
				
			||||||
  off_t       offset;
 | 
					 | 
				
			||||||
  size_t      size;
 | 
					 | 
				
			||||||
} PinosMessageBuffer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* PINOS_MESSAGE_USE_BUFFERS */
 | 
					/* PINOS_MESSAGE_USE_BUFFERS */
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
  uint32_t            seq;
 | 
					  uint32_t            seq;
 | 
				
			||||||
  SpaDirection        direction;
 | 
					  SpaDirection        direction;
 | 
				
			||||||
  uint32_t            port_id;
 | 
					  uint32_t            port_id;
 | 
				
			||||||
  unsigned int        n_buffers;
 | 
					  unsigned int        n_buffers;
 | 
				
			||||||
  PinosMessageBuffer *buffers;
 | 
					  PinosClientNodeBuffer *buffers;
 | 
				
			||||||
} PinosMessageUseBuffers;
 | 
					} PinosMessageUseBuffers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PinosConnection *  pinos_connection_new             (int              fd);
 | 
					PinosConnection *  pinos_connection_new             (int              fd);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										245
									
								
								pinos/client/interfaces.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										245
									
								
								pinos/client/interfaces.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,245 @@
 | 
				
			||||||
 | 
					/* Simple Plugin API
 | 
				
			||||||
 | 
					 * Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU Library General Public
 | 
				
			||||||
 | 
					 * License as published by the Free Software Foundation; either
 | 
				
			||||||
 | 
					 * version 2 of the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 * Library General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Library General Public
 | 
				
			||||||
 | 
					 * License along with this library; if not, write to the
 | 
				
			||||||
 | 
					 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 | 
				
			||||||
 | 
					 * Boston, MA 02110-1301, USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __PINOS_INTERFACES_H__
 | 
				
			||||||
 | 
					#define __PINOS_INTERFACES_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <spa/defs.h>
 | 
				
			||||||
 | 
					#include <spa/props.h>
 | 
				
			||||||
 | 
					#include <spa/format.h>
 | 
				
			||||||
 | 
					#include <spa/port.h>
 | 
				
			||||||
 | 
					#include <spa/node.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _PinosClientNodeBuffer PinosClientNodeBuffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <pinos/client/introspect.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PINOS_CORE_CLIENT_UPDATE 0
 | 
				
			||||||
 | 
					#define PINOS_CORE_SYNC 1
 | 
				
			||||||
 | 
					#define PINOS_CORE_GET_REGISTRY 2
 | 
				
			||||||
 | 
					#define PINOS_CORE_CREATE_NODE 3
 | 
				
			||||||
 | 
					#define PINOS_CORE_CREATE_CLIENT_NODE 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  void (*client_update)       (void          *object,
 | 
				
			||||||
 | 
					                               const SpaDict *props);
 | 
				
			||||||
 | 
					  void (*sync)                (void          *object,
 | 
				
			||||||
 | 
					                               uint32_t       seq);
 | 
				
			||||||
 | 
					  void (*get_registry)        (void          *object,
 | 
				
			||||||
 | 
					                               uint32_t       seq,
 | 
				
			||||||
 | 
					                               uint32_t       new_id);
 | 
				
			||||||
 | 
					  void (*create_node)         (void          *object,
 | 
				
			||||||
 | 
					                               uint32_t       seq,
 | 
				
			||||||
 | 
					                               const char    *factory_name,
 | 
				
			||||||
 | 
					                               const char    *name,
 | 
				
			||||||
 | 
					                               const SpaDict *props,
 | 
				
			||||||
 | 
					                               uint32_t       new_id);
 | 
				
			||||||
 | 
					  void (*create_client_node)  (void          *object,
 | 
				
			||||||
 | 
					                               uint32_t       seq,
 | 
				
			||||||
 | 
					                               const char    *name,
 | 
				
			||||||
 | 
					                               const SpaDict *props,
 | 
				
			||||||
 | 
					                               uint32_t       new_id);
 | 
				
			||||||
 | 
					} PinosCoreInterface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  void (*info)                (void          *object,
 | 
				
			||||||
 | 
					                               PinosCoreInfo *info);
 | 
				
			||||||
 | 
					  void (*done)                (void          *object,
 | 
				
			||||||
 | 
					                               uint32_t       seq);
 | 
				
			||||||
 | 
					  void (*error)               (void          *object,
 | 
				
			||||||
 | 
					                               uint32_t       id,
 | 
				
			||||||
 | 
					                               SpaResult      res,
 | 
				
			||||||
 | 
					                               const char     *error, ...);
 | 
				
			||||||
 | 
					  void (*remove_id)           (void          *object,
 | 
				
			||||||
 | 
					                               uint32_t       id);
 | 
				
			||||||
 | 
					} PinosCoreEvent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define pinos_core_notify_info(r,...)      ((PinosCoreEvent*)r->event)->info(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					#define pinos_core_notify_done(r,...)      ((PinosCoreEvent*)r->event)->done(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					#define pinos_core_notify_error(r,...)     ((PinosCoreEvent*)r->event)->error(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					#define pinos_core_notify_remove_id(r,...) ((PinosCoreEvent*)r->event)->remove_id(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PINOS_REGISTRY_BIND 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  void (*bind)                (void          *object,
 | 
				
			||||||
 | 
					                               uint32_t       id,
 | 
				
			||||||
 | 
					                               uint32_t       new_id);
 | 
				
			||||||
 | 
					} PinosRegistryInterface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  void (*global)              (void          *object,
 | 
				
			||||||
 | 
					                               uint32_t       id,
 | 
				
			||||||
 | 
					                               const char    *type);
 | 
				
			||||||
 | 
					  void (*global_remove)       (void          *object,
 | 
				
			||||||
 | 
					                               uint32_t       id);
 | 
				
			||||||
 | 
					} PinosRegistryEvent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define pinos_registry_notify_global(r,...)        ((PinosRegistryEvent*)r->event)->global(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					#define pinos_registry_notify_global_remove(r,...) ((PinosRegistryEvent*)r->event)->global_remove(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  void (*info)                (void            *object,
 | 
				
			||||||
 | 
					                               PinosModuleInfo *info);
 | 
				
			||||||
 | 
					} PinosModuleEvent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define pinos_module_notify_info(r,...)      ((PinosModuleEvent*)r->event)->info(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  void (*done)                (void          *object,
 | 
				
			||||||
 | 
					                               uint32_t       seq);
 | 
				
			||||||
 | 
					  void (*info)                (void          *object,
 | 
				
			||||||
 | 
					                               PinosNodeInfo *info);
 | 
				
			||||||
 | 
					} PinosNodeEvent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define pinos_node_notify_done(r,...)      ((PinosNodeEvent*)r->event)->done(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					#define pinos_node_notify_info(r,...)      ((PinosNodeEvent*)r->event)->info(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PINOS_CLIENT_NODE_UPDATE        0
 | 
				
			||||||
 | 
					#define PINOS_CLIENT_NODE_PORT_UPDATE   1
 | 
				
			||||||
 | 
					#define PINOS_CLIENT_NODE_STATE_CHANGE  2
 | 
				
			||||||
 | 
					#define PINOS_CLIENT_NODE_EVENT         3
 | 
				
			||||||
 | 
					#define PINOS_CLIENT_NODE_DESTROY       4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _PinosClientNodeBuffer {
 | 
				
			||||||
 | 
					  SpaBuffer  *buffer;
 | 
				
			||||||
 | 
					  uint32_t    mem_id;
 | 
				
			||||||
 | 
					  off_t       offset;
 | 
				
			||||||
 | 
					  size_t      size;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  void (*update)               (void           *object,
 | 
				
			||||||
 | 
					#define PINOS_MESSAGE_NODE_UPDATE_MAX_INPUTS   (1 << 0)
 | 
				
			||||||
 | 
					#define PINOS_MESSAGE_NODE_UPDATE_MAX_OUTPUTS  (1 << 1)
 | 
				
			||||||
 | 
					#define PINOS_MESSAGE_NODE_UPDATE_PROPS        (1 << 2)
 | 
				
			||||||
 | 
					                                uint32_t        change_mask,
 | 
				
			||||||
 | 
					                                unsigned int    max_input_ports,
 | 
				
			||||||
 | 
					                                unsigned int    max_output_ports,
 | 
				
			||||||
 | 
					                                const SpaProps *props);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void (*port_update)          (void              *object,
 | 
				
			||||||
 | 
					                                SpaDirection       direction,
 | 
				
			||||||
 | 
					                                uint32_t           port_id,
 | 
				
			||||||
 | 
					#define PINOS_MESSAGE_PORT_UPDATE_POSSIBLE_FORMATS  (1 << 0)
 | 
				
			||||||
 | 
					#define PINOS_MESSAGE_PORT_UPDATE_FORMAT            (1 << 1)
 | 
				
			||||||
 | 
					#define PINOS_MESSAGE_PORT_UPDATE_PROPS             (1 << 2)
 | 
				
			||||||
 | 
					#define PINOS_MESSAGE_PORT_UPDATE_INFO              (1 << 3)
 | 
				
			||||||
 | 
					                                uint32_t           change_mask,
 | 
				
			||||||
 | 
					                                unsigned int       n_possible_formats,
 | 
				
			||||||
 | 
					                                SpaFormat        **possible_formats,
 | 
				
			||||||
 | 
					                                SpaFormat         *format,
 | 
				
			||||||
 | 
					                                const SpaProps    *props,
 | 
				
			||||||
 | 
					                                const SpaPortInfo *info);
 | 
				
			||||||
 | 
					  void (*state_change)         (void              *object,
 | 
				
			||||||
 | 
					                                SpaNodeState       state);
 | 
				
			||||||
 | 
					  void (*event)                (void              *object,
 | 
				
			||||||
 | 
					                                SpaNodeEvent      *event);
 | 
				
			||||||
 | 
					  void (*destroy)              (void              *object,
 | 
				
			||||||
 | 
					                                uint32_t           seq);
 | 
				
			||||||
 | 
					} PinosClientNodeInterface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  void (*done)                 (void              *object,
 | 
				
			||||||
 | 
					                                uint32_t           seq,
 | 
				
			||||||
 | 
					                                int                datafd);
 | 
				
			||||||
 | 
					  void (*event)                (void              *object,
 | 
				
			||||||
 | 
					                                SpaNodeEvent      *event);
 | 
				
			||||||
 | 
					  void (*add_port)             (void              *object,
 | 
				
			||||||
 | 
					                                uint32_t           seq,
 | 
				
			||||||
 | 
					                                SpaDirection       direction,
 | 
				
			||||||
 | 
					                                uint32_t           port_id);
 | 
				
			||||||
 | 
					  void (*remove_port)          (void              *object,
 | 
				
			||||||
 | 
					                                uint32_t           seq,
 | 
				
			||||||
 | 
					                                SpaDirection       direction,
 | 
				
			||||||
 | 
					                                uint32_t           port_id);
 | 
				
			||||||
 | 
					  void (*set_format)           (void              *object,
 | 
				
			||||||
 | 
					                                uint32_t           seq,
 | 
				
			||||||
 | 
					                                SpaDirection       direction,
 | 
				
			||||||
 | 
					                                uint32_t           port_id,
 | 
				
			||||||
 | 
					                                SpaPortFormatFlags flags,
 | 
				
			||||||
 | 
					                                const SpaFormat   *format);
 | 
				
			||||||
 | 
					  void (*set_property)         (void              *object,
 | 
				
			||||||
 | 
					                                uint32_t           seq,
 | 
				
			||||||
 | 
					                                uint32_t           id,
 | 
				
			||||||
 | 
					                                size_t             size,
 | 
				
			||||||
 | 
					                                void              *value);
 | 
				
			||||||
 | 
					  void (*add_mem)              (void              *object,
 | 
				
			||||||
 | 
					                                SpaDirection       direction,
 | 
				
			||||||
 | 
					                                uint32_t           port_id,
 | 
				
			||||||
 | 
					                                uint32_t           mem_id,
 | 
				
			||||||
 | 
					                                SpaDataType        type,
 | 
				
			||||||
 | 
					                                int                memfd,
 | 
				
			||||||
 | 
					                                uint32_t           flags,
 | 
				
			||||||
 | 
					                                off_t              offset,
 | 
				
			||||||
 | 
					                                size_t             size);
 | 
				
			||||||
 | 
					  void (*use_buffers)          (void              *object,
 | 
				
			||||||
 | 
					                                uint32_t            seq,
 | 
				
			||||||
 | 
					                                SpaDirection        direction,
 | 
				
			||||||
 | 
					                                uint32_t            port_id,
 | 
				
			||||||
 | 
					                                unsigned int        n_buffers,
 | 
				
			||||||
 | 
					                                PinosClientNodeBuffer *buffers);
 | 
				
			||||||
 | 
					  void (*node_command)         (void              *object,
 | 
				
			||||||
 | 
					                                uint32_t           seq,
 | 
				
			||||||
 | 
					                                SpaNodeCommand    *command);
 | 
				
			||||||
 | 
					  void (*port_command)         (void              *object,
 | 
				
			||||||
 | 
					                                uint32_t           port_id,
 | 
				
			||||||
 | 
					                                SpaNodeCommand    *command);
 | 
				
			||||||
 | 
					  void (*transport)            (void              *object,
 | 
				
			||||||
 | 
					                                int                memfd,
 | 
				
			||||||
 | 
					                                off_t              offset,
 | 
				
			||||||
 | 
					                                size_t             size);
 | 
				
			||||||
 | 
					} PinosClientNodeEvent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define pinos_client_node_notify_done(r,...)         ((PinosClientNodeEvent*)r->event)->done(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					#define pinos_client_node_notify_event(r,...)        ((PinosClientNodeEvent*)r->event)->event(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					#define pinos_client_node_notify_add_port(r,...)     ((PinosClientNodeEvent*)r->event)->add_port(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					#define pinos_client_node_notify_remove_port(r,...)  ((PinosClientNodeEvent*)r->event)->remove_port(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					#define pinos_client_node_notify_set_format(r,...)   ((PinosClientNodeEvent*)r->event)->set_format(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					#define pinos_client_node_notify_set_property(r,...) ((PinosClientNodeEvent*)r->event)->set_property(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					#define pinos_client_node_notify_add_mem(r,...)      ((PinosClientNodeEvent*)r->event)->add_mem(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					#define pinos_client_node_notify_use_buffers(r,...)  ((PinosClientNodeEvent*)r->event)->use_buffers(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					#define pinos_client_node_notify_node_command(r,...) ((PinosClientNodeEvent*)r->event)->node_command(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					#define pinos_client_node_notify_port_command(r,...) ((PinosClientNodeEvent*)r->event)->port_command(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					#define pinos_client_node_notify_transport(r,...)    ((PinosClientNodeEvent*)r->event)->transport(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  void (*info)                (void            *object,
 | 
				
			||||||
 | 
					                               PinosClientInfo *info);
 | 
				
			||||||
 | 
					} PinosClientEvent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define pinos_client_notify_info(r,...)      ((PinosClientEvent*)r->event)->info(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  void (*info)                (void          *object,
 | 
				
			||||||
 | 
					                               PinosLinkInfo *info);
 | 
				
			||||||
 | 
					} PinosLinkEvent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define pinos_link_notify_info(r,...)      ((PinosLinkEvent*)r->event)->info(r,__VA_ARGS__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}  /* extern "C" */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __PINOS_INTERFACES_H__ */
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "pinos/client/interfaces.h"
 | 
				
			||||||
#include "pinos/server/core.h"
 | 
					#include "pinos/server/core.h"
 | 
				
			||||||
#include "pinos/server/module.h"
 | 
					#include "pinos/server/module.h"
 | 
				
			||||||
#include "pinos/server/client-node.h"
 | 
					#include "pinos/server/client-node.h"
 | 
				
			||||||
| 
						 | 
					@ -136,14 +137,14 @@ on_link_state_changed (PinosListener  *listener,
 | 
				
			||||||
      pinos_log_debug ("module %p: link %p: state error: %s", impl, link, link->error);
 | 
					      pinos_log_debug ("module %p: link %p: state error: %s", impl, link, link->error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      spa_list_for_each (resource, &link->resource_list, link) {
 | 
					      spa_list_for_each (resource, &link->resource_list, link) {
 | 
				
			||||||
        pinos_client_send_error (resource->client,
 | 
					        pinos_core_notify_error (resource->client->core_resource,
 | 
				
			||||||
                                 resource,
 | 
					                                 resource->id,
 | 
				
			||||||
                                 SPA_RESULT_ERROR,
 | 
					                                 SPA_RESULT_ERROR,
 | 
				
			||||||
                                 link->error);
 | 
					                                 link->error);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if (info->info->client) {
 | 
					      if (info->info->client) {
 | 
				
			||||||
        pinos_client_send_error (info->info->client,
 | 
					        pinos_core_notify_error (info->info->client->core_resource,
 | 
				
			||||||
                                 info->resource,
 | 
					                                 info->resource->id,
 | 
				
			||||||
                                 SPA_RESULT_ERROR,
 | 
					                                 SPA_RESULT_ERROR,
 | 
				
			||||||
                                 link->error);
 | 
					                                 link->error);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
| 
						 | 
					@ -219,8 +220,8 @@ error:
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    pinos_log_error ("module %p: can't link node '%s'", impl, error);
 | 
					    pinos_log_error ("module %p: can't link node '%s'", impl, error);
 | 
				
			||||||
    if (info->info->client) {
 | 
					    if (info->info->client) {
 | 
				
			||||||
      pinos_client_send_error (info->info->client,
 | 
					      pinos_core_notify_error (info->info->client->core_resource,
 | 
				
			||||||
                               info->resource,
 | 
					                               info->resource->id,
 | 
				
			||||||
                               SPA_RESULT_ERROR,
 | 
					                               SPA_RESULT_ERROR,
 | 
				
			||||||
                               error);
 | 
					                               error);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,6 +31,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pinos/client/pinos.h"
 | 
					#include "pinos/client/pinos.h"
 | 
				
			||||||
#include "pinos/client/log.h"
 | 
					#include "pinos/client/log.h"
 | 
				
			||||||
 | 
					#include "pinos/client/interfaces.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pinos/server/core.h"
 | 
					#include "pinos/server/core.h"
 | 
				
			||||||
#include "pinos/server/node.h"
 | 
					#include "pinos/server/node.h"
 | 
				
			||||||
| 
						 | 
					@ -78,6 +79,7 @@ typedef struct {
 | 
				
			||||||
  int                  fd;
 | 
					  int                  fd;
 | 
				
			||||||
  SpaSource           *source;
 | 
					  SpaSource           *source;
 | 
				
			||||||
  PinosConnection     *connection;
 | 
					  PinosConnection     *connection;
 | 
				
			||||||
 | 
					  PinosListener        resource_added;
 | 
				
			||||||
} PinosProtocolNativeClient;
 | 
					} PinosProtocolNativeClient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -93,27 +95,610 @@ client_destroy (PinosProtocolNativeClient *this)
 | 
				
			||||||
  free (this);
 | 
					  free (this);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static SpaResult
 | 
					typedef void (*MarshallFunc) (void *object, void *data, size_t size);
 | 
				
			||||||
client_send_func (void             *object,
 | 
					 | 
				
			||||||
                  uint32_t          id,
 | 
					 | 
				
			||||||
                  PinosMessageType  type,
 | 
					 | 
				
			||||||
                  void             *message,
 | 
					 | 
				
			||||||
                  bool              flush,
 | 
					 | 
				
			||||||
                  void             *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PinosProtocolNativeClient *client = data;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinos_log_debug ("protocol-native %p: sending message %d to %u of client %p",
 | 
					static void
 | 
				
			||||||
      client->impl, type, id, client);
 | 
					core_event_info (void          *object,
 | 
				
			||||||
 | 
					                 PinosCoreInfo *info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageCoreInfo m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  m.info = info;
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_CORE_INFO,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					core_event_done (void          *object,
 | 
				
			||||||
 | 
					                 uint32_t       seq)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageNotifyDone m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  m.seq = seq;
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_NOTIFY_DONE,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					core_event_error (void          *object,
 | 
				
			||||||
 | 
					                  uint32_t       id,
 | 
				
			||||||
 | 
					                  SpaResult      res,
 | 
				
			||||||
 | 
					                  const char     *error, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageError m;
 | 
				
			||||||
 | 
					  char buffer[128];
 | 
				
			||||||
 | 
					  va_list ap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  va_start (ap, error);
 | 
				
			||||||
 | 
					  vsnprintf (buffer, sizeof (buffer), error, ap);
 | 
				
			||||||
 | 
					  va_end (ap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  m.id = id;
 | 
				
			||||||
 | 
					  m.res = res;
 | 
				
			||||||
 | 
					  m.error = buffer;
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_ERROR,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					core_event_remove_id (void          *object,
 | 
				
			||||||
 | 
					                      uint32_t       id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageRemoveId m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  m.id = id;
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_REMOVE_ID,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					core_client_update (void  *object,
 | 
				
			||||||
 | 
					                    void  *data,
 | 
				
			||||||
 | 
					                    size_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosMessageClientUpdate *m = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ((PinosCoreInterface*)resource->interface)->client_update (resource, m->props);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					core_sync (void  *object,
 | 
				
			||||||
 | 
					           void  *data,
 | 
				
			||||||
 | 
					           size_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosMessageSync *m = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ((PinosCoreInterface*)resource->interface)->sync (resource, m->seq);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					core_get_registry (void  *object,
 | 
				
			||||||
 | 
					                   void  *data,
 | 
				
			||||||
 | 
					                   size_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosMessageGetRegistry *m = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ((PinosCoreInterface*)resource->interface)->get_registry (resource, m->seq, m->new_id);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					core_create_node (void  *object,
 | 
				
			||||||
 | 
					                  void  *data,
 | 
				
			||||||
 | 
					                  size_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosMessageCreateNode *m = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ((PinosCoreInterface*)resource->interface)->create_node (resource,
 | 
				
			||||||
 | 
					                                                           m->seq,
 | 
				
			||||||
 | 
					                                                           m->factory_name,
 | 
				
			||||||
 | 
					                                                           m->name,
 | 
				
			||||||
 | 
					                                                           m->props,
 | 
				
			||||||
 | 
					                                                           m->new_id);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					core_create_client_node (void  *object,
 | 
				
			||||||
 | 
					                         void  *data,
 | 
				
			||||||
 | 
					                         size_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosMessageCreateClientNode *m = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ((PinosCoreInterface*)resource->interface)->create_client_node (resource,
 | 
				
			||||||
 | 
					                                                                  m->seq,
 | 
				
			||||||
 | 
					                                                                  m->name,
 | 
				
			||||||
 | 
					                                                                  m->props,
 | 
				
			||||||
 | 
					                                                                  m->new_id);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					registry_event_global (void          *object,
 | 
				
			||||||
 | 
					                       uint32_t       id,
 | 
				
			||||||
 | 
					                       const char    *type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageNotifyGlobal m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  m.id = id;
 | 
				
			||||||
 | 
					  m.type = type;
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_NOTIFY_GLOBAL,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					registry_event_global_remove (void          *object,
 | 
				
			||||||
 | 
					                              uint32_t       id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageNotifyGlobalRemove m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  m.id = id;
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_NOTIFY_GLOBAL_REMOVE,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					registry_bind (void  *object,
 | 
				
			||||||
 | 
					               void  *data,
 | 
				
			||||||
 | 
					               size_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosMessageBind *m = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ((PinosRegistryInterface*)resource->interface)->bind (resource,
 | 
				
			||||||
 | 
					                                                        m->id,
 | 
				
			||||||
 | 
					                                                        m->new_id);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					module_event_info (void            *object,
 | 
				
			||||||
 | 
					                   PinosModuleInfo *info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageModuleInfo m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  m.info = info;
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_MODULE_INFO,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					node_event_done (void          *object,
 | 
				
			||||||
 | 
					                 uint32_t       seq)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageCreateNodeDone m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  m.seq = seq;
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_CREATE_NODE_DONE,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					node_event_info (void          *object,
 | 
				
			||||||
 | 
					                 PinosNodeInfo *info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageNodeInfo m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  m.info = info;
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_NODE_INFO,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					client_event_info (void          *object,
 | 
				
			||||||
 | 
					                   PinosClientInfo *info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageClientInfo m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  m.info = info;
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_CLIENT_INFO,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					client_node_event_done (void          *object,
 | 
				
			||||||
 | 
					                        uint32_t       seq,
 | 
				
			||||||
 | 
					                        int            datafd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageCreateClientNodeDone m = { seq, datafd };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinos_connection_add_message (client->connection,
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
                                id,
 | 
					                                resource->id,
 | 
				
			||||||
                                type,
 | 
					                                PINOS_MESSAGE_CREATE_CLIENT_NODE_DONE,
 | 
				
			||||||
                                message);
 | 
					                                &m);
 | 
				
			||||||
  if (flush)
 | 
					 | 
				
			||||||
  pinos_connection_flush (client->connection);
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return SPA_RESULT_OK;
 | 
					static void
 | 
				
			||||||
 | 
					client_node_event_event (void              *object,
 | 
				
			||||||
 | 
					                         SpaNodeEvent      *event)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageNodeEvent m = { event };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_NODE_EVENT,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					client_node_event_add_port (void              *object,
 | 
				
			||||||
 | 
					                            uint32_t           seq,
 | 
				
			||||||
 | 
					                            SpaDirection       direction,
 | 
				
			||||||
 | 
					                            uint32_t           port_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageAddPort m = { seq, direction, port_id };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_ADD_PORT,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					client_node_event_remove_port (void              *object,
 | 
				
			||||||
 | 
					                               uint32_t           seq,
 | 
				
			||||||
 | 
					                               SpaDirection       direction,
 | 
				
			||||||
 | 
					                               uint32_t           port_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageRemovePort m = { seq, direction, port_id };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_REMOVE_PORT,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					client_node_event_set_format (void              *object,
 | 
				
			||||||
 | 
					                              uint32_t           seq,
 | 
				
			||||||
 | 
					                              SpaDirection       direction,
 | 
				
			||||||
 | 
					                              uint32_t           port_id,
 | 
				
			||||||
 | 
					                              SpaPortFormatFlags flags,
 | 
				
			||||||
 | 
					                              const SpaFormat   *format)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageSetFormat m = { seq, direction, port_id, flags, format };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_SET_FORMAT,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					client_node_event_set_property (void              *object,
 | 
				
			||||||
 | 
					                                uint32_t           seq,
 | 
				
			||||||
 | 
					                                uint32_t           id,
 | 
				
			||||||
 | 
					                                size_t             size,
 | 
				
			||||||
 | 
					                                void              *value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageSetProperty m = { seq, id, size, value };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_SET_PROPERTY,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					client_node_event_add_mem (void              *object,
 | 
				
			||||||
 | 
					                           SpaDirection       direction,
 | 
				
			||||||
 | 
					                           uint32_t           port_id,
 | 
				
			||||||
 | 
					                           uint32_t           mem_id,
 | 
				
			||||||
 | 
					                           SpaDataType        type,
 | 
				
			||||||
 | 
					                           int                memfd,
 | 
				
			||||||
 | 
					                           uint32_t           flags,
 | 
				
			||||||
 | 
					                           off_t              offset,
 | 
				
			||||||
 | 
					                           size_t             size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageAddMem m = { direction, port_id, mem_id, type, memfd, flags, offset, size };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_ADD_MEM,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					client_node_event_use_buffers (void                  *object,
 | 
				
			||||||
 | 
					                               uint32_t               seq,
 | 
				
			||||||
 | 
					                               SpaDirection           direction,
 | 
				
			||||||
 | 
					                               uint32_t               port_id,
 | 
				
			||||||
 | 
					                               unsigned int           n_buffers,
 | 
				
			||||||
 | 
					                               PinosClientNodeBuffer *buffers)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageUseBuffers m = { seq, direction, port_id, n_buffers, buffers };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_USE_BUFFERS,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					client_node_event_node_command (void              *object,
 | 
				
			||||||
 | 
					                                uint32_t           seq,
 | 
				
			||||||
 | 
					                                SpaNodeCommand    *command)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageNodeCommand m = { seq, command };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_NODE_COMMAND,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					client_node_event_port_command (void              *object,
 | 
				
			||||||
 | 
					                                uint32_t           port_id,
 | 
				
			||||||
 | 
					                                SpaNodeCommand    *command)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessagePortCommand m = { port_id, command };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_PORT_COMMAND,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					client_node_event_transport (void              *object,
 | 
				
			||||||
 | 
					                             int                memfd,
 | 
				
			||||||
 | 
					                             off_t              offset,
 | 
				
			||||||
 | 
					                             size_t             size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageTransportUpdate m = { memfd, offset, size };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_TRANSPORT_UPDATE,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					client_node_update (void  *object,
 | 
				
			||||||
 | 
					                    void  *data,
 | 
				
			||||||
 | 
					                    size_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosMessageNodeUpdate *m = data;
 | 
				
			||||||
 | 
					  ((PinosClientNodeInterface*)resource->interface)->update (object,
 | 
				
			||||||
 | 
					                                                            m->change_mask,
 | 
				
			||||||
 | 
					                                                            m->max_input_ports,
 | 
				
			||||||
 | 
					                                                            m->max_output_ports,
 | 
				
			||||||
 | 
					                                                            m->props);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					client_node_port_update (void  *object,
 | 
				
			||||||
 | 
					                         void  *data,
 | 
				
			||||||
 | 
					                         size_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosMessagePortUpdate *m = data;
 | 
				
			||||||
 | 
					  ((PinosClientNodeInterface*)resource->interface)->port_update (object,
 | 
				
			||||||
 | 
					                                                                 m->direction,
 | 
				
			||||||
 | 
					                                                                 m->port_id,
 | 
				
			||||||
 | 
					                                                                 m->change_mask,
 | 
				
			||||||
 | 
					                                                                 m->n_possible_formats,
 | 
				
			||||||
 | 
					                                                                 m->possible_formats,
 | 
				
			||||||
 | 
					                                                                 m->format,
 | 
				
			||||||
 | 
					                                                                 m->props,
 | 
				
			||||||
 | 
					                                                                 m->info);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					client_node_state_change (void  *object,
 | 
				
			||||||
 | 
					                          void  *data,
 | 
				
			||||||
 | 
					                          size_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosMessageNodeStateChange *m = data;
 | 
				
			||||||
 | 
					  ((PinosClientNodeInterface*)resource->interface)->state_change (object,
 | 
				
			||||||
 | 
					                                                                  m->state);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					client_node_event (void   *object,
 | 
				
			||||||
 | 
					                   void   *data,
 | 
				
			||||||
 | 
					                   size_t  size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosMessageNodeEvent *m = data;
 | 
				
			||||||
 | 
					  ((PinosClientNodeInterface*)resource->interface)->event (object,
 | 
				
			||||||
 | 
					                                                           m->event);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					client_node_destroy (void   *object,
 | 
				
			||||||
 | 
					                     void   *data,
 | 
				
			||||||
 | 
					                     size_t  size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosMessageDestroy *m = data;
 | 
				
			||||||
 | 
					  ((PinosClientNodeInterface*)resource->interface)->destroy (object,
 | 
				
			||||||
 | 
					                                                             m->seq);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					link_event_info (void          *object,
 | 
				
			||||||
 | 
					                 PinosLinkInfo *info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosProtocolNativeClient *client = resource->client->protocol_private;
 | 
				
			||||||
 | 
					  PinosMessageLinkInfo m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  m.info = info;
 | 
				
			||||||
 | 
					  pinos_connection_add_message (client->connection,
 | 
				
			||||||
 | 
					                                resource->id,
 | 
				
			||||||
 | 
					                                PINOS_MESSAGE_LINK_INFO,
 | 
				
			||||||
 | 
					                                &m);
 | 
				
			||||||
 | 
					  pinos_connection_flush (client->connection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					on_resource_added (PinosListener *listener,
 | 
				
			||||||
 | 
					                   PinosClient   *client,
 | 
				
			||||||
 | 
					                   PinosResource *resource)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (resource->type == resource->core->uri.core) {
 | 
				
			||||||
 | 
					    static const PinosCoreEvent core_event = {
 | 
				
			||||||
 | 
					      &core_event_info,
 | 
				
			||||||
 | 
					      &core_event_done,
 | 
				
			||||||
 | 
					      &core_event_error,
 | 
				
			||||||
 | 
					      &core_event_remove_id
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static const MarshallFunc core_marshall[] = {
 | 
				
			||||||
 | 
					      [PINOS_MESSAGE_CLIENT_UPDATE] = &core_client_update,
 | 
				
			||||||
 | 
					      [PINOS_MESSAGE_SYNC] = &core_sync,
 | 
				
			||||||
 | 
					      [PINOS_MESSAGE_GET_REGISTRY] = &core_get_registry,
 | 
				
			||||||
 | 
					      [PINOS_MESSAGE_CREATE_NODE] = &core_create_node,
 | 
				
			||||||
 | 
					      [PINOS_MESSAGE_CREATE_CLIENT_NODE] = &core_create_client_node
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    resource->event = &core_event;
 | 
				
			||||||
 | 
					    resource->marshall = &core_marshall;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else if (resource->type == resource->core->uri.registry) {
 | 
				
			||||||
 | 
					    static const PinosRegistryEvent registry_event = {
 | 
				
			||||||
 | 
					      ®istry_event_global,
 | 
				
			||||||
 | 
					      ®istry_event_global_remove,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static const MarshallFunc registry_marshall[] = {
 | 
				
			||||||
 | 
					      [PINOS_MESSAGE_BIND] = ®istry_bind,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    resource->event = ®istry_event;
 | 
				
			||||||
 | 
					    resource->marshall = ®istry_marshall;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else if (resource->type == resource->core->uri.module) {
 | 
				
			||||||
 | 
					    static const PinosModuleEvent module_event = {
 | 
				
			||||||
 | 
					      &module_event_info,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    resource->event = &module_event;
 | 
				
			||||||
 | 
					    resource->marshall = NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else if (resource->type == resource->core->uri.node) {
 | 
				
			||||||
 | 
					    static const PinosNodeEvent node_event = {
 | 
				
			||||||
 | 
					      &node_event_done,
 | 
				
			||||||
 | 
					      &node_event_info,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    resource->event = &node_event;
 | 
				
			||||||
 | 
					    resource->marshall = NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else if (resource->type == resource->core->uri.client) {
 | 
				
			||||||
 | 
					    static const PinosClientEvent client_event = {
 | 
				
			||||||
 | 
					      &client_event_info,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    resource->event = &client_event;
 | 
				
			||||||
 | 
					    resource->marshall = NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else if (resource->type == resource->core->uri.client_node) {
 | 
				
			||||||
 | 
					    static const PinosClientNodeEvent client_node_events = {
 | 
				
			||||||
 | 
					      &client_node_event_done,
 | 
				
			||||||
 | 
					      &client_node_event_event,
 | 
				
			||||||
 | 
					      &client_node_event_add_port,
 | 
				
			||||||
 | 
					      &client_node_event_remove_port,
 | 
				
			||||||
 | 
					      &client_node_event_set_format,
 | 
				
			||||||
 | 
					      &client_node_event_set_property,
 | 
				
			||||||
 | 
					      &client_node_event_add_mem,
 | 
				
			||||||
 | 
					      &client_node_event_use_buffers,
 | 
				
			||||||
 | 
					      &client_node_event_node_command,
 | 
				
			||||||
 | 
					      &client_node_event_port_command,
 | 
				
			||||||
 | 
					      &client_node_event_transport,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static const MarshallFunc client_node_marshall[] = {
 | 
				
			||||||
 | 
					      [PINOS_MESSAGE_NODE_UPDATE] = &client_node_update,
 | 
				
			||||||
 | 
					      [PINOS_MESSAGE_PORT_UPDATE] = &client_node_port_update,
 | 
				
			||||||
 | 
					      [PINOS_MESSAGE_NODE_STATE_CHANGE] = &client_node_state_change,
 | 
				
			||||||
 | 
					      [PINOS_MESSAGE_NODE_EVENT] = &client_node_event,
 | 
				
			||||||
 | 
					      [PINOS_MESSAGE_DESTROY] = &client_node_destroy,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    resource->event = &client_node_events;
 | 
				
			||||||
 | 
					    resource->marshall = &client_node_marshall;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else if (resource->type == resource->core->uri.link) {
 | 
				
			||||||
 | 
					    static const PinosLinkEvent link_event = {
 | 
				
			||||||
 | 
					      &link_event_info,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    resource->event = &link_event;
 | 
				
			||||||
 | 
					    resource->marshall = NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -138,6 +723,7 @@ connection_data (SpaSource *source,
 | 
				
			||||||
  while (pinos_connection_get_next (conn, &type, &id, &size)) {
 | 
					  while (pinos_connection_get_next (conn, &type, &id, &size)) {
 | 
				
			||||||
    PinosResource *resource;
 | 
					    PinosResource *resource;
 | 
				
			||||||
    void *message = alloca (size);
 | 
					    void *message = alloca (size);
 | 
				
			||||||
 | 
					    const MarshallFunc *marshall;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pinos_log_debug ("protocol-native %p: got message %d from %u", client->impl, type, id);
 | 
					    pinos_log_debug ("protocol-native %p: got message %d from %u", client->impl, type, id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -151,10 +737,11 @@ connection_data (SpaSource *source,
 | 
				
			||||||
      pinos_log_error ("protocol-native %p: unknown resource %u", client->impl, id);
 | 
					      pinos_log_error ("protocol-native %p: unknown resource %u", client->impl, id);
 | 
				
			||||||
      continue;
 | 
					      continue;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    marshall = resource->marshall;
 | 
				
			||||||
    pinos_resource_dispatch (resource,
 | 
					    if (marshall[type])
 | 
				
			||||||
                             type,
 | 
					      marshall[type] (resource, message, size);
 | 
				
			||||||
                             message);
 | 
					    else
 | 
				
			||||||
 | 
					      pinos_log_error ("protocol-native %p: function %d not implemented", client->impl, type);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -198,14 +785,16 @@ client_new (PinosProtocolNative *impl,
 | 
				
			||||||
  if (client == NULL)
 | 
					  if (client == NULL)
 | 
				
			||||||
    goto no_client;
 | 
					    goto no_client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  client->protocol_private = this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  this->client = client;
 | 
					  this->client = client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinos_client_set_send (client,
 | 
					 | 
				
			||||||
                         client_send_func,
 | 
					 | 
				
			||||||
                         this);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  spa_list_insert (impl->client_list.prev, &this->link);
 | 
					  spa_list_insert (impl->client_list.prev, &this->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pinos_signal_add (&client->resource_added,
 | 
				
			||||||
 | 
					                    &this->resource_added,
 | 
				
			||||||
 | 
					                    on_resource_added);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinos_global_bind (impl->core->global,
 | 
					  pinos_global_bind (impl->core->global,
 | 
				
			||||||
                     client,
 | 
					                     client,
 | 
				
			||||||
                     0,
 | 
					                     0,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,7 +29,7 @@
 | 
				
			||||||
#include <sys/eventfd.h>
 | 
					#include <sys/eventfd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pinos/client/pinos.h"
 | 
					#include "pinos/client/pinos.h"
 | 
				
			||||||
#include "pinos/client/connection.h"
 | 
					#include "pinos/client/interfaces.h"
 | 
				
			||||||
#include "pinos/client/serialize.h"
 | 
					#include "pinos/client/serialize.h"
 | 
				
			||||||
#include "pinos/client/transport.h"
 | 
					#include "pinos/client/transport.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -216,38 +216,22 @@ spa_proxy_node_send_command (SpaNode        *node,
 | 
				
			||||||
    case SPA_NODE_COMMAND_FLUSH:
 | 
					    case SPA_NODE_COMMAND_FLUSH:
 | 
				
			||||||
    case SPA_NODE_COMMAND_DRAIN:
 | 
					    case SPA_NODE_COMMAND_DRAIN:
 | 
				
			||||||
    case SPA_NODE_COMMAND_MARKER:
 | 
					    case SPA_NODE_COMMAND_MARKER:
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      PinosMessageNodeCommand cnc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      /* send start */
 | 
					      /* send start */
 | 
				
			||||||
      cnc.seq = this->seq++;
 | 
					      pinos_client_node_notify_node_command (this->resource,
 | 
				
			||||||
      cnc.command = command;
 | 
					                                             this->seq,
 | 
				
			||||||
      pinos_client_send_message (this->resource->client,
 | 
					                                             command);
 | 
				
			||||||
                                 this->resource,
 | 
					 | 
				
			||||||
                                 PINOS_MESSAGE_NODE_COMMAND,
 | 
					 | 
				
			||||||
                                 &cnc,
 | 
					 | 
				
			||||||
                                 true);
 | 
					 | 
				
			||||||
      if (command->type == SPA_NODE_COMMAND_START)
 | 
					      if (command->type == SPA_NODE_COMMAND_START)
 | 
				
			||||||
        send_need_input (this);
 | 
					        send_need_input (this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      res = SPA_RESULT_RETURN_ASYNC (cnc.seq);
 | 
					      res = SPA_RESULT_RETURN_ASYNC (this->seq++);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case SPA_NODE_COMMAND_CLOCK_UPDATE:
 | 
					    case SPA_NODE_COMMAND_CLOCK_UPDATE:
 | 
				
			||||||
    {
 | 
					      pinos_client_node_notify_node_command (this->resource,
 | 
				
			||||||
      PinosMessageNodeCommand cnc;
 | 
					                                             this->seq++,
 | 
				
			||||||
 | 
					                                             command);
 | 
				
			||||||
      /* send start */
 | 
					 | 
				
			||||||
      cnc.command = command;
 | 
					 | 
				
			||||||
      pinos_client_send_message (this->resource->client,
 | 
					 | 
				
			||||||
                                 this->resource,
 | 
					 | 
				
			||||||
                                 PINOS_MESSAGE_NODE_COMMAND,
 | 
					 | 
				
			||||||
                                 &cnc,
 | 
					 | 
				
			||||||
                                 true);
 | 
					 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return res;
 | 
					  return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -326,22 +310,29 @@ spa_proxy_node_get_port_ids (SpaNode       *node,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
do_update_port (SpaProxy          *this,
 | 
					do_update_port (SpaProxy          *this,
 | 
				
			||||||
                PinosMessagePortUpdate *pu)
 | 
					                SpaDirection       direction,
 | 
				
			||||||
 | 
					                uint32_t           port_id,
 | 
				
			||||||
 | 
					                uint32_t           change_mask,
 | 
				
			||||||
 | 
					                unsigned int       n_possible_formats,
 | 
				
			||||||
 | 
					                SpaFormat        **possible_formats,
 | 
				
			||||||
 | 
					                SpaFormat         *format,
 | 
				
			||||||
 | 
					                const SpaProps    *props,
 | 
				
			||||||
 | 
					                const SpaPortInfo *info)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  SpaProxyPort *port;
 | 
					  SpaProxyPort *port;
 | 
				
			||||||
  unsigned int i;
 | 
					  unsigned int i;
 | 
				
			||||||
  size_t size;
 | 
					  size_t size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (pu->direction == SPA_DIRECTION_INPUT) {
 | 
					  if (direction == SPA_DIRECTION_INPUT) {
 | 
				
			||||||
    port = &this->in_ports[pu->port_id];
 | 
					    port = &this->in_ports[port_id];
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    port = &this->out_ports[pu->port_id];
 | 
					    port = &this->out_ports[port_id];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (pu->change_mask & PINOS_MESSAGE_PORT_UPDATE_POSSIBLE_FORMATS) {
 | 
					  if (change_mask & PINOS_MESSAGE_PORT_UPDATE_POSSIBLE_FORMATS) {
 | 
				
			||||||
    for (i = 0; i < port->n_formats; i++)
 | 
					    for (i = 0; i < port->n_formats; i++)
 | 
				
			||||||
      free (port->formats[i]);
 | 
					      free (port->formats[i]);
 | 
				
			||||||
    port->n_formats = pu->n_possible_formats;
 | 
					    port->n_formats = n_possible_formats;
 | 
				
			||||||
    if (port->n_formats)
 | 
					    if (port->n_formats)
 | 
				
			||||||
      port->formats = realloc (port->formats, port->n_formats * sizeof (SpaFormat *));
 | 
					      port->formats = realloc (port->formats, port->n_formats * sizeof (SpaFormat *));
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
| 
						 | 
					@ -349,33 +340,33 @@ do_update_port (SpaProxy               *this,
 | 
				
			||||||
      port->formats = NULL;
 | 
					      port->formats = NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    for (i = 0; i < port->n_formats; i++) {
 | 
					    for (i = 0; i < port->n_formats; i++) {
 | 
				
			||||||
      size = pinos_serialize_format_get_size (pu->possible_formats[i]);
 | 
					      size = pinos_serialize_format_get_size (possible_formats[i]);
 | 
				
			||||||
      port->formats[i] = size ? pinos_serialize_format_copy_into (malloc (size), pu->possible_formats[i]) : NULL;
 | 
					      port->formats[i] = size ? pinos_serialize_format_copy_into (malloc (size), possible_formats[i]) : NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (pu->change_mask & PINOS_MESSAGE_PORT_UPDATE_FORMAT) {
 | 
					  if (change_mask & PINOS_MESSAGE_PORT_UPDATE_FORMAT) {
 | 
				
			||||||
    if (port->format)
 | 
					    if (port->format)
 | 
				
			||||||
      free (port->format);
 | 
					      free (port->format);
 | 
				
			||||||
    size = pinos_serialize_format_get_size (pu->format);
 | 
					    size = pinos_serialize_format_get_size (format);
 | 
				
			||||||
    port->format = size ? pinos_serialize_format_copy_into (malloc (size), pu->format) : NULL;
 | 
					    port->format = size ? pinos_serialize_format_copy_into (malloc (size), format) : NULL;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (pu->change_mask & PINOS_MESSAGE_PORT_UPDATE_PROPS) {
 | 
					  if (change_mask & PINOS_MESSAGE_PORT_UPDATE_PROPS) {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (pu->change_mask & PINOS_MESSAGE_PORT_UPDATE_INFO && pu->info) {
 | 
					  if (change_mask & PINOS_MESSAGE_PORT_UPDATE_INFO && info) {
 | 
				
			||||||
    if (port->info)
 | 
					    if (port->info)
 | 
				
			||||||
      free (port->info);
 | 
					      free (port->info);
 | 
				
			||||||
    size = pinos_serialize_port_info_get_size (pu->info);
 | 
					    size = pinos_serialize_port_info_get_size (info);
 | 
				
			||||||
    port->info = size ? pinos_serialize_port_info_copy_into (malloc (size), pu->info) : NULL;
 | 
					    port->info = size ? pinos_serialize_port_info_copy_into (malloc (size), info) : NULL;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!port->valid) {
 | 
					  if (!port->valid) {
 | 
				
			||||||
    spa_log_info (this->log, "proxy %p: adding port %d", this, pu->port_id);
 | 
					    spa_log_info (this->log, "proxy %p: adding port %d", this, port_id);
 | 
				
			||||||
    port->format = NULL;
 | 
					    port->format = NULL;
 | 
				
			||||||
    port->valid = true;
 | 
					    port->valid = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (pu->direction == SPA_DIRECTION_INPUT)
 | 
					    if (direction == SPA_DIRECTION_INPUT)
 | 
				
			||||||
      this->n_inputs++;
 | 
					      this->n_inputs++;
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      this->n_outputs++;
 | 
					      this->n_outputs++;
 | 
				
			||||||
| 
						 | 
					@ -388,20 +379,18 @@ clear_port (SpaProxy     *this,
 | 
				
			||||||
            SpaDirection  direction,
 | 
					            SpaDirection  direction,
 | 
				
			||||||
            uint32_t      port_id)
 | 
					            uint32_t      port_id)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PinosMessagePortUpdate pu;
 | 
					  do_update_port (this,
 | 
				
			||||||
 | 
					                  direction,
 | 
				
			||||||
  pu.change_mask = PINOS_MESSAGE_PORT_UPDATE_POSSIBLE_FORMATS |
 | 
					                  port_id,
 | 
				
			||||||
 | 
					                  PINOS_MESSAGE_PORT_UPDATE_POSSIBLE_FORMATS |
 | 
				
			||||||
                  PINOS_MESSAGE_PORT_UPDATE_FORMAT |
 | 
					                  PINOS_MESSAGE_PORT_UPDATE_FORMAT |
 | 
				
			||||||
                  PINOS_MESSAGE_PORT_UPDATE_PROPS |
 | 
					                  PINOS_MESSAGE_PORT_UPDATE_PROPS |
 | 
				
			||||||
                   PINOS_MESSAGE_PORT_UPDATE_INFO;
 | 
					                  PINOS_MESSAGE_PORT_UPDATE_INFO,
 | 
				
			||||||
  pu.direction = direction;
 | 
					                  0,
 | 
				
			||||||
  pu.port_id = port_id;
 | 
					                  NULL,
 | 
				
			||||||
  pu.n_possible_formats = 0;
 | 
					                  NULL,
 | 
				
			||||||
  pu.possible_formats = NULL;
 | 
					                  NULL,
 | 
				
			||||||
  pu.format = NULL;
 | 
					                  NULL);
 | 
				
			||||||
  pu.props = NULL;
 | 
					 | 
				
			||||||
  pu.info = NULL;
 | 
					 | 
				
			||||||
  do_update_port (this, &pu);
 | 
					 | 
				
			||||||
  clear_buffers (this, port);
 | 
					  clear_buffers (this, port);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -503,7 +492,6 @@ spa_proxy_node_port_set_format (SpaNode            *node,
 | 
				
			||||||
                                const SpaFormat    *format)
 | 
					                                const SpaFormat    *format)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  SpaProxy *this;
 | 
					  SpaProxy *this;
 | 
				
			||||||
  PinosMessageSetFormat sf;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (node == NULL)
 | 
					  if (node == NULL)
 | 
				
			||||||
    return SPA_RESULT_INVALID_ARGUMENTS;
 | 
					    return SPA_RESULT_INVALID_ARGUMENTS;
 | 
				
			||||||
| 
						 | 
					@ -516,17 +504,14 @@ spa_proxy_node_port_set_format (SpaNode            *node,
 | 
				
			||||||
  if (this->resource == NULL)
 | 
					  if (this->resource == NULL)
 | 
				
			||||||
    return SPA_RESULT_OK;
 | 
					    return SPA_RESULT_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  sf.seq = this->seq++;
 | 
					  pinos_client_node_notify_set_format (this->resource,
 | 
				
			||||||
  sf.direction = direction;
 | 
					                                       this->seq,
 | 
				
			||||||
  sf.port_id = port_id;
 | 
					                                       direction,
 | 
				
			||||||
  sf.flags = flags;
 | 
					                                       port_id,
 | 
				
			||||||
  sf.format = (SpaFormat *) format;
 | 
					                                       flags,
 | 
				
			||||||
  pinos_client_send_message (this->resource->client,
 | 
					                                       format);
 | 
				
			||||||
                             this->resource,
 | 
					
 | 
				
			||||||
                             PINOS_MESSAGE_SET_FORMAT,
 | 
					  return SPA_RESULT_RETURN_ASYNC (this->seq++);
 | 
				
			||||||
                             &sf,
 | 
					 | 
				
			||||||
                             true);
 | 
					 | 
				
			||||||
  return SPA_RESULT_RETURN_ASYNC (sf.seq);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static SpaResult
 | 
					static SpaResult
 | 
				
			||||||
| 
						 | 
					@ -648,10 +633,8 @@ spa_proxy_node_port_use_buffers (SpaNode         *node,
 | 
				
			||||||
  SpaProxy *this;
 | 
					  SpaProxy *this;
 | 
				
			||||||
  SpaProxyPort *port;
 | 
					  SpaProxyPort *port;
 | 
				
			||||||
  unsigned int i, j;
 | 
					  unsigned int i, j;
 | 
				
			||||||
  PinosMessageAddMem am;
 | 
					 | 
				
			||||||
  PinosMessageUseBuffers ub;
 | 
					 | 
				
			||||||
  size_t n_mem;
 | 
					  size_t n_mem;
 | 
				
			||||||
  PinosMessageBuffer *mb;
 | 
					  PinosClientNodeBuffer *mb;
 | 
				
			||||||
  SpaMetaShared *msh;
 | 
					  SpaMetaShared *msh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (node == NULL)
 | 
					  if (node == NULL)
 | 
				
			||||||
| 
						 | 
					@ -671,7 +654,7 @@ spa_proxy_node_port_use_buffers (SpaNode         *node,
 | 
				
			||||||
  clear_buffers (this, port);
 | 
					  clear_buffers (this, port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (n_buffers > 0) {
 | 
					  if (n_buffers > 0) {
 | 
				
			||||||
    mb = alloca (n_buffers * sizeof (PinosMessageBuffer));
 | 
					    mb = alloca (n_buffers * sizeof (PinosClientNodeBuffer));
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    mb = NULL;
 | 
					    mb = NULL;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -696,24 +679,20 @@ spa_proxy_node_port_use_buffers (SpaNode         *node,
 | 
				
			||||||
    b->buffer.datas = b->datas;
 | 
					    b->buffer.datas = b->datas;
 | 
				
			||||||
    b->buffer.metas = b->metas;
 | 
					    b->buffer.metas = b->metas;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    am.direction = direction;
 | 
					 | 
				
			||||||
    am.port_id = port_id;
 | 
					 | 
				
			||||||
    am.mem_id = n_mem++;
 | 
					 | 
				
			||||||
    am.type = SPA_DATA_TYPE_MEMFD;
 | 
					 | 
				
			||||||
    am.memfd = msh->fd;
 | 
					 | 
				
			||||||
    am.flags = msh->flags;
 | 
					 | 
				
			||||||
    am.offset = msh->offset;
 | 
					 | 
				
			||||||
    am.size = msh->size;
 | 
					 | 
				
			||||||
    pinos_client_send_message (this->resource->client,
 | 
					 | 
				
			||||||
                               this->resource,
 | 
					 | 
				
			||||||
                               PINOS_MESSAGE_ADD_MEM,
 | 
					 | 
				
			||||||
                               &am,
 | 
					 | 
				
			||||||
                               false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    mb[i].buffer = &b->buffer;
 | 
					    mb[i].buffer = &b->buffer;
 | 
				
			||||||
    mb[i].mem_id = am.mem_id;
 | 
					    mb[i].mem_id = n_mem++;
 | 
				
			||||||
    mb[i].offset = 0;
 | 
					    mb[i].offset = 0;
 | 
				
			||||||
    mb[i].size = am.size;
 | 
					    mb[i].size = msh->size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pinos_client_node_notify_add_mem (this->resource,
 | 
				
			||||||
 | 
					                                      direction,
 | 
				
			||||||
 | 
					                                      port_id,
 | 
				
			||||||
 | 
					                                      mb[i].mem_id,
 | 
				
			||||||
 | 
					                                      SPA_DATA_TYPE_MEMFD,
 | 
				
			||||||
 | 
					                                      msh->fd,
 | 
				
			||||||
 | 
					                                      msh->flags,
 | 
				
			||||||
 | 
					                                      msh->offset,
 | 
				
			||||||
 | 
					                                      msh->size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (j = 0; j < buffers[i]->n_metas; j++) {
 | 
					    for (j = 0; j < buffers[i]->n_metas; j++) {
 | 
				
			||||||
      memcpy (&b->buffer.metas[j], &buffers[i]->metas[j], sizeof (SpaMeta));
 | 
					      memcpy (&b->buffer.metas[j], &buffers[i]->metas[j], sizeof (SpaMeta));
 | 
				
			||||||
| 
						 | 
					@ -727,19 +706,15 @@ spa_proxy_node_port_use_buffers (SpaNode         *node,
 | 
				
			||||||
      switch (d->type) {
 | 
					      switch (d->type) {
 | 
				
			||||||
        case SPA_DATA_TYPE_DMABUF:
 | 
					        case SPA_DATA_TYPE_DMABUF:
 | 
				
			||||||
        case SPA_DATA_TYPE_MEMFD:
 | 
					        case SPA_DATA_TYPE_MEMFD:
 | 
				
			||||||
          am.direction = direction;
 | 
					          pinos_client_node_notify_add_mem (this->resource,
 | 
				
			||||||
          am.port_id = port_id;
 | 
					                                            direction,
 | 
				
			||||||
          am.mem_id = n_mem;
 | 
					                                            port_id,
 | 
				
			||||||
          am.type = d->type;
 | 
					                                            n_mem,
 | 
				
			||||||
          am.memfd = d->fd;
 | 
					                                            d->type,
 | 
				
			||||||
          am.flags = d->flags;
 | 
					                                            d->fd,
 | 
				
			||||||
          am.offset = d->mapoffset;
 | 
					                                            d->flags,
 | 
				
			||||||
          am.size = d->maxsize;
 | 
					                                            d->mapoffset,
 | 
				
			||||||
          pinos_client_send_message (this->resource->client,
 | 
					                                            d->maxsize);
 | 
				
			||||||
                                     this->resource,
 | 
					 | 
				
			||||||
                                     PINOS_MESSAGE_ADD_MEM,
 | 
					 | 
				
			||||||
                                     &am,
 | 
					 | 
				
			||||||
                                     false);
 | 
					 | 
				
			||||||
          b->buffer.datas[j].type = SPA_DATA_TYPE_ID;
 | 
					          b->buffer.datas[j].type = SPA_DATA_TYPE_ID;
 | 
				
			||||||
          b->buffer.datas[j].data = SPA_UINT32_TO_PTR (n_mem);
 | 
					          b->buffer.datas[j].data = SPA_UINT32_TO_PTR (n_mem);
 | 
				
			||||||
          n_mem++;
 | 
					          n_mem++;
 | 
				
			||||||
| 
						 | 
					@ -757,18 +732,14 @@ spa_proxy_node_port_use_buffers (SpaNode         *node,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ub.seq = this->seq++;
 | 
					  pinos_client_node_notify_use_buffers (this->resource,
 | 
				
			||||||
  ub.direction = direction;
 | 
					                                        this->seq,
 | 
				
			||||||
  ub.port_id = port_id;
 | 
					                                        direction,
 | 
				
			||||||
  ub.n_buffers = n_buffers;
 | 
					                                        port_id,
 | 
				
			||||||
  ub.buffers = mb;
 | 
					                                        n_buffers,
 | 
				
			||||||
  pinos_client_send_message (this->resource->client,
 | 
					                                        mb);
 | 
				
			||||||
                             this->resource,
 | 
					 | 
				
			||||||
                             PINOS_MESSAGE_USE_BUFFERS,
 | 
					 | 
				
			||||||
                             &ub,
 | 
					 | 
				
			||||||
                             true);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return SPA_RESULT_RETURN_ASYNC (ub.seq);
 | 
					  return SPA_RESULT_RETURN_ASYNC (this->seq++);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static SpaResult
 | 
					static SpaResult
 | 
				
			||||||
| 
						 | 
					@ -914,86 +885,110 @@ handle_node_event (SpaProxy     *this,
 | 
				
			||||||
  return SPA_RESULT_OK;
 | 
					  return SPA_RESULT_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static SpaResult
 | 
					static void
 | 
				
			||||||
client_node_dispatch_func (void             *object,
 | 
					client_node_update (void           *object,
 | 
				
			||||||
                           PinosMessageType  type,
 | 
					                    uint32_t        change_mask,
 | 
				
			||||||
                           void             *message,
 | 
					                    unsigned int    max_input_ports,
 | 
				
			||||||
                           void             *data)
 | 
					                    unsigned int    max_output_ports,
 | 
				
			||||||
 | 
					                    const SpaProps *props)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PinosClientNode *node = data;
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosClientNode *node = resource->object;
 | 
				
			||||||
  PinosClientNodeImpl *impl = SPA_CONTAINER_OF (node, PinosClientNodeImpl, this);
 | 
					  PinosClientNodeImpl *impl = SPA_CONTAINER_OF (node, PinosClientNodeImpl, this);
 | 
				
			||||||
  SpaProxy *this = &impl->proxy;
 | 
					  SpaProxy *this = &impl->proxy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  switch (type) {
 | 
					  if (change_mask & PINOS_MESSAGE_NODE_UPDATE_MAX_INPUTS)
 | 
				
			||||||
    default:
 | 
					    this->max_inputs = max_input_ports;
 | 
				
			||||||
      spa_log_error (this->log, "proxy %p: got unexpected command %d", this, type);
 | 
					  if (change_mask & PINOS_MESSAGE_NODE_UPDATE_MAX_OUTPUTS)
 | 
				
			||||||
      break;
 | 
					    this->max_outputs = max_output_ports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case PINOS_MESSAGE_NODE_UPDATE:
 | 
					  spa_log_info (this->log, "proxy %p: got node update max_in %u, max_out %u", this,
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      PinosMessageNodeUpdate *nu = message;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (nu->change_mask & PINOS_MESSAGE_NODE_UPDATE_MAX_INPUTS)
 | 
					 | 
				
			||||||
        this->max_inputs = nu->max_input_ports;
 | 
					 | 
				
			||||||
      if (nu->change_mask & PINOS_MESSAGE_NODE_UPDATE_MAX_OUTPUTS)
 | 
					 | 
				
			||||||
        this->max_outputs = nu->max_output_ports;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      spa_log_info (this->log, "proxy %p: got node update %d, max_in %u, max_out %u", this, type,
 | 
					 | 
				
			||||||
      this->max_inputs, this->max_outputs);
 | 
					      this->max_inputs, this->max_outputs);
 | 
				
			||||||
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case PINOS_MESSAGE_PORT_UPDATE:
 | 
					static void
 | 
				
			||||||
 | 
					client_node_port_update (void              *object,
 | 
				
			||||||
 | 
					                         SpaDirection       direction,
 | 
				
			||||||
 | 
					                         uint32_t           port_id,
 | 
				
			||||||
 | 
					                         uint32_t           change_mask,
 | 
				
			||||||
 | 
					                         unsigned int       n_possible_formats,
 | 
				
			||||||
 | 
					                         SpaFormat        **possible_formats,
 | 
				
			||||||
 | 
					                         SpaFormat         *format,
 | 
				
			||||||
 | 
					                         const SpaProps    *props,
 | 
				
			||||||
 | 
					                         const SpaPortInfo *info)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
      PinosMessagePortUpdate *pu = message;
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosClientNode *node = resource->object;
 | 
				
			||||||
 | 
					  PinosClientNodeImpl *impl = SPA_CONTAINER_OF (node, PinosClientNodeImpl, this);
 | 
				
			||||||
 | 
					  SpaProxy *this = &impl->proxy;
 | 
				
			||||||
  bool remove;
 | 
					  bool remove;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      spa_log_info (this->log, "proxy %p: got port update %d", this, type);
 | 
					  spa_log_info (this->log, "proxy %p: got port update", this);
 | 
				
			||||||
      if (!CHECK_PORT_ID (this, pu->direction, pu->port_id))
 | 
					  if (!CHECK_PORT_ID (this, direction, port_id))
 | 
				
			||||||
        break;
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      remove = (pu->change_mask == 0);
 | 
					  remove = (change_mask == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (remove) {
 | 
					  if (remove) {
 | 
				
			||||||
        do_uninit_port (this, pu->direction, pu->port_id);
 | 
					    do_uninit_port (this, direction, port_id);
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
        do_update_port (this, pu);
 | 
					    do_update_port (this,
 | 
				
			||||||
 | 
					                    direction,
 | 
				
			||||||
 | 
					                    port_id,
 | 
				
			||||||
 | 
					                    change_mask,
 | 
				
			||||||
 | 
					                    n_possible_formats,
 | 
				
			||||||
 | 
					                    possible_formats,
 | 
				
			||||||
 | 
					                    format,
 | 
				
			||||||
 | 
					                    props,
 | 
				
			||||||
 | 
					                    info);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case PINOS_MESSAGE_NODE_STATE_CHANGE:
 | 
					static void
 | 
				
			||||||
 | 
					client_node_state_change (void              *object,
 | 
				
			||||||
 | 
					                          SpaNodeState       state)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
      PinosMessageNodeStateChange *sc = message;
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosClientNode *node = resource->object;
 | 
				
			||||||
 | 
					  PinosClientNodeImpl *impl = SPA_CONTAINER_OF (node, PinosClientNodeImpl, this);
 | 
				
			||||||
 | 
					  SpaProxy *this = &impl->proxy;
 | 
				
			||||||
  SpaNodeState old = this->node.state;
 | 
					  SpaNodeState old = this->node.state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      spa_log_info (this->log, "proxy %p: got node state change %d -> %d", this, old, sc->state);
 | 
					  spa_log_info (this->log, "proxy %p: got node state change %d -> %d", this, old, state);
 | 
				
			||||||
      this->node.state = sc->state;
 | 
					  this->node.state = state;
 | 
				
			||||||
  if (old == SPA_NODE_STATE_INIT)
 | 
					  if (old == SPA_NODE_STATE_INIT)
 | 
				
			||||||
    send_async_complete (this, 0, SPA_RESULT_OK);
 | 
					    send_async_complete (this, 0, SPA_RESULT_OK);
 | 
				
			||||||
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case PINOS_MESSAGE_ADD_MEM:
 | 
					static void
 | 
				
			||||||
      break;
 | 
					client_node_event (void              *object,
 | 
				
			||||||
    case PINOS_MESSAGE_USE_BUFFERS:
 | 
					                   SpaNodeEvent      *event)
 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    case PINOS_MESSAGE_NODE_EVENT:
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
      PinosMessageNodeEvent *cne = message;
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
      handle_node_event (this, cne->event);
 | 
					  PinosClientNode *node = resource->object;
 | 
				
			||||||
      break;
 | 
					  PinosClientNodeImpl *impl = SPA_CONTAINER_OF (node, PinosClientNodeImpl, this);
 | 
				
			||||||
 | 
					  SpaProxy *this = &impl->proxy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  handle_node_event (this, event);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
    case PINOS_MESSAGE_DESTROY:
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					client_node_destroy (void              *object,
 | 
				
			||||||
 | 
					                     uint32_t           seq)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosClientNode *node = resource->object;
 | 
				
			||||||
  pinos_client_node_destroy (node);
 | 
					  pinos_client_node_destroy (node);
 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return SPA_RESULT_OK;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PinosClientNodeInterface client_node_interface = {
 | 
				
			||||||
 | 
					  &client_node_update,
 | 
				
			||||||
 | 
					  &client_node_port_update,
 | 
				
			||||||
 | 
					  &client_node_state_change,
 | 
				
			||||||
 | 
					  &client_node_event,
 | 
				
			||||||
 | 
					  &client_node_destroy,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
proxy_on_data_fd_events (SpaSource *source)
 | 
					proxy_on_data_fd_events (SpaSource *source)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1088,21 +1083,15 @@ on_transport_changed (PinosListener   *listener,
 | 
				
			||||||
  PinosClientNodeImpl *impl = SPA_CONTAINER_OF (listener, PinosClientNodeImpl, transport_changed);
 | 
					  PinosClientNodeImpl *impl = SPA_CONTAINER_OF (listener, PinosClientNodeImpl, transport_changed);
 | 
				
			||||||
  PinosClientNode *this = &impl->this;
 | 
					  PinosClientNode *this = &impl->this;
 | 
				
			||||||
  PinosTransportInfo info;
 | 
					  PinosTransportInfo info;
 | 
				
			||||||
  PinosMessageTransportUpdate tu;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (this->resource == NULL)
 | 
					  if (this->resource == NULL)
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinos_transport_get_info (node->transport, &info);
 | 
					  pinos_transport_get_info (node->transport, &info);
 | 
				
			||||||
 | 
					  pinos_client_node_notify_transport (this->resource,
 | 
				
			||||||
  tu.memfd = info.memfd;
 | 
					                                      info.memfd,
 | 
				
			||||||
  tu.offset = info.offset;
 | 
					                                      info.offset,
 | 
				
			||||||
  tu.size = info.size;
 | 
					                                      info.size);
 | 
				
			||||||
  pinos_client_send_message (this->resource->client,
 | 
					 | 
				
			||||||
                             this->resource,
 | 
					 | 
				
			||||||
                             PINOS_MESSAGE_TRANSPORT_UPDATE,
 | 
					 | 
				
			||||||
                             &tu,
 | 
					 | 
				
			||||||
                             true);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -1249,9 +1238,7 @@ pinos_client_node_new (PinosClient     *client,
 | 
				
			||||||
                    &impl->global_added,
 | 
					                    &impl->global_added,
 | 
				
			||||||
                    on_global_added);
 | 
					                    on_global_added);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinos_resource_set_dispatch (this->resource,
 | 
					  this->resource->interface = &client_node_interface;
 | 
				
			||||||
                               client_node_dispatch_func,
 | 
					 | 
				
			||||||
                               this);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return this;
 | 
					  return this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,9 @@
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pinos/client/pinos.h"
 | 
					#include "pinos/client/pinos.h"
 | 
				
			||||||
 | 
					#include "pinos/client/interfaces.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pinos/server/client.h"
 | 
					#include "pinos/server/client.h"
 | 
				
			||||||
#include "pinos/server/resource.h"
 | 
					#include "pinos/server/resource.h"
 | 
				
			||||||
| 
						 | 
					@ -26,29 +28,8 @@
 | 
				
			||||||
typedef struct
 | 
					typedef struct
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PinosClient this;
 | 
					  PinosClient this;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  PinosSendFunc   send_func;
 | 
					 | 
				
			||||||
  void           *send_data;
 | 
					 | 
				
			||||||
} PinosClientImpl;
 | 
					} PinosClientImpl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
static SpaResult
 | 
					 | 
				
			||||||
client_dispatch_func (void             *object,
 | 
					 | 
				
			||||||
                      PinosMessageType  type,
 | 
					 | 
				
			||||||
                      void             *message,
 | 
					 | 
				
			||||||
                      void             *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PinosResource *resource = object;
 | 
					 | 
				
			||||||
  PinosClient *client = resource->object;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  switch (type) {
 | 
					 | 
				
			||||||
    default:
 | 
					 | 
				
			||||||
      pinos_log_warn ("client %p: unhandled message %d", client, type);
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return SPA_RESULT_OK;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
client_unbind_func (void *data)
 | 
					client_unbind_func (void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -64,8 +45,6 @@ client_bind_func (PinosGlobal *global,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PinosClient *this = global->object;
 | 
					  PinosClient *this = global->object;
 | 
				
			||||||
  PinosResource *resource;
 | 
					  PinosResource *resource;
 | 
				
			||||||
  PinosMessageClientInfo m;
 | 
					 | 
				
			||||||
  PinosClientInfo info;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  resource = pinos_resource_new (client,
 | 
					  resource = pinos_resource_new (client,
 | 
				
			||||||
                                 id,
 | 
					                                 id,
 | 
				
			||||||
| 
						 | 
					@ -75,27 +54,18 @@ client_bind_func (PinosGlobal *global,
 | 
				
			||||||
  if (resource == NULL)
 | 
					  if (resource == NULL)
 | 
				
			||||||
    goto no_mem;
 | 
					    goto no_mem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinos_resource_set_dispatch (resource,
 | 
					 | 
				
			||||||
                               client_dispatch_func,
 | 
					 | 
				
			||||||
                               global);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  pinos_log_debug ("client %p: bound to %d", global->object, resource->id);
 | 
					  pinos_log_debug ("client %p: bound to %d", global->object, resource->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  spa_list_insert (this->resource_list.prev, &resource->link);
 | 
					  spa_list_insert (this->resource_list.prev, &resource->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  m.info = &info;
 | 
					  this->info.change_mask = ~0;
 | 
				
			||||||
  info.id = global->id;
 | 
					  pinos_client_notify_info (resource, &this->info);
 | 
				
			||||||
  info.change_mask = ~0;
 | 
					
 | 
				
			||||||
  info.props = this->properties ? &this->properties->dict : NULL;
 | 
					  return SPA_RESULT_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return pinos_client_send_message (client,
 | 
					 | 
				
			||||||
                                    resource,
 | 
					 | 
				
			||||||
                                    PINOS_MESSAGE_CLIENT_INFO,
 | 
					 | 
				
			||||||
                                    &m,
 | 
					 | 
				
			||||||
                                    true);
 | 
					 | 
				
			||||||
no_mem:
 | 
					no_mem:
 | 
				
			||||||
  pinos_client_send_error (client,
 | 
					  pinos_core_notify_error (client->core_resource,
 | 
				
			||||||
                           client->core_resource,
 | 
					                           client->core_resource->id,
 | 
				
			||||||
                           SPA_RESULT_NO_MEMORY,
 | 
					                           SPA_RESULT_NO_MEMORY,
 | 
				
			||||||
                           "no memory");
 | 
					                           "no memory");
 | 
				
			||||||
  return SPA_RESULT_NO_MEMORY;
 | 
					  return SPA_RESULT_NO_MEMORY;
 | 
				
			||||||
| 
						 | 
					@ -146,6 +116,9 @@ pinos_client_new (PinosCore       *core,
 | 
				
			||||||
                                        this,
 | 
					                                        this,
 | 
				
			||||||
                                        client_bind_func);
 | 
					                                        client_bind_func);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  this->info.id = this->global->id;
 | 
				
			||||||
 | 
					  this->info.props = this->properties ? &this->properties->dict : NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return this;
 | 
					  return this;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -188,113 +161,10 @@ pinos_client_destroy (PinosClient * client)
 | 
				
			||||||
  free (impl);
 | 
					  free (impl);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					 | 
				
			||||||
pinos_client_set_send (PinosClient     *client,
 | 
					 | 
				
			||||||
                       PinosSendFunc    func,
 | 
					 | 
				
			||||||
                       void            *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PinosClientImpl *impl = SPA_CONTAINER_OF (client, PinosClientImpl, this);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  impl->send_func = func;
 | 
					 | 
				
			||||||
  impl->send_data = data;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static SpaResult
 | 
					 | 
				
			||||||
do_send_message (PinosAccessData *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PinosClientImpl *impl = SPA_CONTAINER_OF (data->client, PinosClientImpl, this);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (data->res == SPA_RESULT_SKIPPED) {
 | 
					 | 
				
			||||||
    data->res = SPA_RESULT_OK;
 | 
					 | 
				
			||||||
  } else if (data->res == SPA_RESULT_NO_PERMISSION) {
 | 
					 | 
				
			||||||
    pinos_client_send_error (data->client,
 | 
					 | 
				
			||||||
                             data->resource,
 | 
					 | 
				
			||||||
                             data->res,
 | 
					 | 
				
			||||||
                             "no permission");
 | 
					 | 
				
			||||||
  } else if (SPA_RESULT_IS_ERROR (data->res)) {
 | 
					 | 
				
			||||||
    pinos_client_send_error (data->client,
 | 
					 | 
				
			||||||
                             data->resource,
 | 
					 | 
				
			||||||
                             data->res,
 | 
					 | 
				
			||||||
                             "error %d", data->res);
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    data->res = impl->send_func (data->resource,
 | 
					 | 
				
			||||||
                                 data->resource->id,
 | 
					 | 
				
			||||||
                                 data->opcode,
 | 
					 | 
				
			||||||
                                 data->message,
 | 
					 | 
				
			||||||
                                 data->flush,
 | 
					 | 
				
			||||||
                                 impl->send_data);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return data->res;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
SpaResult
 | 
					 | 
				
			||||||
pinos_client_send_message (PinosClient   *client,
 | 
					 | 
				
			||||||
                           PinosResource *resource,
 | 
					 | 
				
			||||||
                           uint32_t       opcode,
 | 
					 | 
				
			||||||
                           void          *message,
 | 
					 | 
				
			||||||
                           bool           flush)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PinosClientImpl *impl = SPA_CONTAINER_OF (client, PinosClientImpl, this);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (impl->send_func) {
 | 
					 | 
				
			||||||
    PinosAccessData data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    data.client = client;
 | 
					 | 
				
			||||||
    data.resource = resource;
 | 
					 | 
				
			||||||
    data.opcode = opcode;
 | 
					 | 
				
			||||||
    data.message = message;
 | 
					 | 
				
			||||||
    data.flush = flush;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    data.res = SPA_RESULT_OK;
 | 
					 | 
				
			||||||
    pinos_signal_emit (&client->core->access.check_send,
 | 
					 | 
				
			||||||
                       do_send_message,
 | 
					 | 
				
			||||||
                       &data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (SPA_RESULT_IS_ASYNC (data.res))
 | 
					 | 
				
			||||||
      return data.res;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return do_send_message (&data);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  pinos_log_error ("client %p: send func not implemented", client);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return SPA_RESULT_NOT_IMPLEMENTED;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
SpaResult
 | 
					 | 
				
			||||||
pinos_client_send_error (PinosClient   *client,
 | 
					 | 
				
			||||||
                         PinosResource *resource,
 | 
					 | 
				
			||||||
                         SpaResult      res,
 | 
					 | 
				
			||||||
                         const char    *message,
 | 
					 | 
				
			||||||
                         ...)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PinosMessageError m;
 | 
					 | 
				
			||||||
  char buffer[128];
 | 
					 | 
				
			||||||
  va_list ap;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  va_start (ap, message);
 | 
					 | 
				
			||||||
  vsnprintf (buffer, sizeof (buffer), message, ap);
 | 
					 | 
				
			||||||
  va_end (ap);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  m.id = resource->id;
 | 
					 | 
				
			||||||
  m.res = res;
 | 
					 | 
				
			||||||
  m.error = buffer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  pinos_log_error ("client %p: %u send error %d (%s)", client, resource->id, res, buffer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return pinos_client_send_message (client,
 | 
					 | 
				
			||||||
				    client->core_resource,
 | 
					 | 
				
			||||||
                                    PINOS_MESSAGE_ERROR,
 | 
					 | 
				
			||||||
                                    &m,
 | 
					 | 
				
			||||||
                                    true);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
pinos_client_update_properties (PinosClient     *client,
 | 
					pinos_client_update_properties (PinosClient     *client,
 | 
				
			||||||
                                const SpaDict   *dict)
 | 
					                                const SpaDict   *dict)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PinosMessageClientInfo m;
 | 
					 | 
				
			||||||
  PinosClientInfo info;
 | 
					 | 
				
			||||||
  PinosResource *resource;
 | 
					  PinosResource *resource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (client->properties == NULL) {
 | 
					  if (client->properties == NULL) {
 | 
				
			||||||
| 
						 | 
					@ -309,16 +179,10 @@ pinos_client_update_properties (PinosClient     *client,
 | 
				
			||||||
                            dict->items[i].value);
 | 
					                            dict->items[i].value);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  m.info = &info;
 | 
					  client->info.change_mask = 1 << 0;
 | 
				
			||||||
  info.id = client->global->id;
 | 
					  client->info.props = client->properties ? &client->properties->dict : NULL;
 | 
				
			||||||
  info.change_mask = 1 << 0;
 | 
					 | 
				
			||||||
  info.props = client->properties ? &client->properties->dict : NULL;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  spa_list_for_each (resource, &client->resource_list, link) {
 | 
					  spa_list_for_each (resource, &client->resource_list, link) {
 | 
				
			||||||
    pinos_client_send_message (client,
 | 
					    pinos_client_notify_info (resource, &client->info);
 | 
				
			||||||
                               resource,
 | 
					 | 
				
			||||||
                               PINOS_MESSAGE_CLIENT_INFO,
 | 
					 | 
				
			||||||
                               &m,
 | 
					 | 
				
			||||||
                               true);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,6 +28,7 @@ typedef struct _PinosClient PinosClient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <sys/socket.h>
 | 
					#include <sys/socket.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <pinos/client/introspect.h>
 | 
				
			||||||
#include <pinos/client/properties.h>
 | 
					#include <pinos/client/properties.h>
 | 
				
			||||||
#include <pinos/client/sig.h>
 | 
					#include <pinos/client/sig.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,9 +53,12 @@ struct _PinosClient {
 | 
				
			||||||
  PinosGlobal *global;
 | 
					  PinosGlobal *global;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  PinosProperties *properties;
 | 
					  PinosProperties *properties;
 | 
				
			||||||
 | 
					  PinosClientInfo  info;
 | 
				
			||||||
  bool             ucred_valid;
 | 
					  bool             ucred_valid;
 | 
				
			||||||
  struct ucred     ucred;
 | 
					  struct ucred     ucred;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void *protocol_private;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  PinosResource *core_resource;
 | 
					  PinosResource *core_resource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  PinosMap objects;
 | 
					  PinosMap objects;
 | 
				
			||||||
| 
						 | 
					@ -76,21 +80,6 @@ PinosClient *   pinos_client_new                  (PinosCore       *core,
 | 
				
			||||||
                                                   PinosProperties *properties);
 | 
					                                                   PinosProperties *properties);
 | 
				
			||||||
void            pinos_client_destroy              (PinosClient     *client);
 | 
					void            pinos_client_destroy              (PinosClient     *client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void            pinos_client_set_send             (PinosClient     *client,
 | 
					 | 
				
			||||||
                                                   PinosSendFunc    func,
 | 
					 | 
				
			||||||
                                                   void            *data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
SpaResult       pinos_client_send_message         (PinosClient     *client,
 | 
					 | 
				
			||||||
                                                   PinosResource   *resource,
 | 
					 | 
				
			||||||
                                                   uint32_t         opcode,
 | 
					 | 
				
			||||||
                                                   void            *message,
 | 
					 | 
				
			||||||
                                                   bool             flush);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
SpaResult       pinos_client_send_error           (PinosClient     *client,
 | 
					 | 
				
			||||||
                                                   PinosResource   *resource,
 | 
					 | 
				
			||||||
                                                   SpaResult        res,
 | 
					 | 
				
			||||||
                                                   const char      *message, ...);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void            pinos_client_update_properties    (PinosClient     *client,
 | 
					void            pinos_client_update_properties    (PinosClient     *client,
 | 
				
			||||||
                                                   const SpaDict   *dict);
 | 
					                                                   const SpaDict   *dict);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,6 +19,7 @@
 | 
				
			||||||
#include <time.h>
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <pinos/client/pinos.h>
 | 
					#include <pinos/client/pinos.h>
 | 
				
			||||||
 | 
					#include <pinos/client/interfaces.h>
 | 
				
			||||||
#include <pinos/server/core.h>
 | 
					#include <pinos/server/core.h>
 | 
				
			||||||
#include <pinos/server/data-loop.h>
 | 
					#include <pinos/server/data-loop.h>
 | 
				
			||||||
#include <pinos/server/client-node.h>
 | 
					#include <pinos/server/client-node.h>
 | 
				
			||||||
| 
						 | 
					@ -36,46 +37,39 @@ typedef struct {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} PinosCoreImpl;
 | 
					} PinosCoreImpl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static SpaResult
 | 
					static void
 | 
				
			||||||
registry_dispatch_func (void             *object,
 | 
					registry_bind (void     *object,
 | 
				
			||||||
                        PinosMessageType  type,
 | 
					               uint32_t  id,
 | 
				
			||||||
                        void             *message,
 | 
					               uint32_t  new_id)
 | 
				
			||||||
                        void             *data)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  SpaResult res;
 | 
					 | 
				
			||||||
  PinosResource *resource = object;
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
  PinosClient *client = resource->client;
 | 
					  PinosClient *client = resource->client;
 | 
				
			||||||
  PinosCore *this = data;
 | 
					  PinosCore *core = resource->core;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  switch (type) {
 | 
					 | 
				
			||||||
    case PINOS_MESSAGE_BIND:
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      PinosMessageBind *m = message;
 | 
					 | 
				
			||||||
  PinosGlobal *global;
 | 
					  PinosGlobal *global;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      spa_list_for_each (global, &this->global_list, link)
 | 
					  spa_list_for_each (global, &core->global_list, link)
 | 
				
			||||||
        if (global->id == m->id)
 | 
					    if (global->id == id)
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (&global->link == &this->global_list) {
 | 
					  if (&global->link == &core->global_list)
 | 
				
			||||||
        pinos_client_send_error (client,
 | 
					    goto no_id;
 | 
				
			||||||
                                 resource,
 | 
					
 | 
				
			||||||
 | 
					  pinos_log_debug ("global %p: bind object id %d to %d", global, id, new_id);
 | 
				
			||||||
 | 
					  pinos_global_bind (global, client, 0, new_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					no_id:
 | 
				
			||||||
 | 
					  pinos_core_notify_error (client->core_resource,
 | 
				
			||||||
 | 
					                           resource->id,
 | 
				
			||||||
                           SPA_RESULT_INVALID_OBJECT_ID,
 | 
					                           SPA_RESULT_INVALID_OBJECT_ID,
 | 
				
			||||||
                                 "unknown object id %u", m->id);
 | 
					                           "unknown object id %u", id);
 | 
				
			||||||
        return SPA_RESULT_ERROR;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      pinos_log_debug ("global %p: bind object id %d to %d", global, m->id, m->new_id);
 | 
					 | 
				
			||||||
      res = pinos_global_bind (global, client, 0, m->new_id);
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    default:
 | 
					 | 
				
			||||||
      pinos_log_error ("unhandled message %d", type);
 | 
					 | 
				
			||||||
      res = SPA_RESULT_NOT_IMPLEMENTED;
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return res;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PinosRegistryInterface registry_interface = {
 | 
				
			||||||
 | 
					  ®istry_bind
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
destroy_registry_resource (void *object)
 | 
					destroy_registry_resource (void *object)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -83,135 +77,139 @@ destroy_registry_resource (void *object)
 | 
				
			||||||
  spa_list_remove (&resource->link);
 | 
					  spa_list_remove (&resource->link);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static SpaResult
 | 
					static void
 | 
				
			||||||
core_dispatch_func (void             *object,
 | 
					core_client_update (void          *object,
 | 
				
			||||||
                    PinosMessageType  type,
 | 
					                    const SpaDict *props)
 | 
				
			||||||
                    void             *message,
 | 
					{
 | 
				
			||||||
                    void             *data)
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pinos_client_update_properties (resource->client, props);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					core_sync (void    *object,
 | 
				
			||||||
 | 
					           uint32_t seq)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pinos_core_notify_done (resource, seq);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					core_get_registry (void     *object,
 | 
				
			||||||
 | 
					                   uint32_t  seq,
 | 
				
			||||||
 | 
					                   uint32_t  new_id)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PinosResource *resource = object;
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
  PinosClient *client = resource->client;
 | 
					  PinosClient *client = resource->client;
 | 
				
			||||||
  PinosCore *this = data;
 | 
					  PinosCore *this = resource->core;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  switch (type) {
 | 
					 | 
				
			||||||
    case PINOS_MESSAGE_CLIENT_UPDATE:
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      PinosMessageClientUpdate *m = message;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      pinos_client_update_properties (client,
 | 
					 | 
				
			||||||
                                      m->props);
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    case PINOS_MESSAGE_SYNC:
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      PinosMessageSync *m = message;
 | 
					 | 
				
			||||||
      PinosMessageNotifyDone r;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      r.seq = m->seq;
 | 
					 | 
				
			||||||
      pinos_client_send_message (client,
 | 
					 | 
				
			||||||
                                 resource,
 | 
					 | 
				
			||||||
                                 PINOS_MESSAGE_NOTIFY_DONE,
 | 
					 | 
				
			||||||
                                 &r,
 | 
					 | 
				
			||||||
                                 true);
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    case PINOS_MESSAGE_GET_REGISTRY:
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      PinosMessageGetRegistry *m = message;
 | 
					 | 
				
			||||||
  PinosGlobal *global;
 | 
					  PinosGlobal *global;
 | 
				
			||||||
      PinosMessageNotifyDone nd;
 | 
					 | 
				
			||||||
  PinosResource *registry_resource;
 | 
					  PinosResource *registry_resource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      registry_resource = pinos_resource_new (resource->client,
 | 
					  registry_resource = pinos_resource_new (client,
 | 
				
			||||||
                                              m->new_id,
 | 
					                                          new_id,
 | 
				
			||||||
                                          this->uri.registry,
 | 
					                                          this->uri.registry,
 | 
				
			||||||
                                          this,
 | 
					                                          this,
 | 
				
			||||||
                                          destroy_registry_resource);
 | 
					                                          destroy_registry_resource);
 | 
				
			||||||
  if (registry_resource == NULL)
 | 
					  if (registry_resource == NULL)
 | 
				
			||||||
    goto no_mem;
 | 
					    goto no_mem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      pinos_resource_set_dispatch (registry_resource,
 | 
					  registry_resource->interface = ®istry_interface;
 | 
				
			||||||
                                   registry_dispatch_func,
 | 
					 | 
				
			||||||
                                   this);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  spa_list_insert (this->registry_resource_list.prev, ®istry_resource->link);
 | 
					  spa_list_insert (this->registry_resource_list.prev, ®istry_resource->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      spa_list_for_each (global, &this->global_list, link) {
 | 
					  spa_list_for_each (global, &this->global_list, link)
 | 
				
			||||||
        PinosMessageNotifyGlobal ng;
 | 
					    pinos_registry_notify_global (registry_resource,
 | 
				
			||||||
 | 
					                                  global->id,
 | 
				
			||||||
 | 
					                                  spa_id_map_get_uri (this->uri.map, global->type));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ng.id = global->id;
 | 
					  pinos_core_notify_done (client->core_resource, seq);
 | 
				
			||||||
        ng.type = spa_id_map_get_uri (this->uri.map, global->type);
 | 
					
 | 
				
			||||||
        pinos_client_send_message (client,
 | 
					  return;
 | 
				
			||||||
                                   registry_resource,
 | 
					
 | 
				
			||||||
                                   PINOS_MESSAGE_NOTIFY_GLOBAL,
 | 
					no_mem:
 | 
				
			||||||
                                   &ng,
 | 
					  pinos_core_notify_error (client->core_resource,
 | 
				
			||||||
                                   false);
 | 
					                           resource->id,
 | 
				
			||||||
 | 
					                           SPA_RESULT_NO_MEMORY,
 | 
				
			||||||
 | 
					                           "no memory");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
      nd.seq = m->seq;
 | 
					
 | 
				
			||||||
      pinos_client_send_message (client,
 | 
					static void
 | 
				
			||||||
                                 client->core_resource,
 | 
					core_create_node (void          *object,
 | 
				
			||||||
                                 PINOS_MESSAGE_NOTIFY_DONE,
 | 
					                  uint32_t       seq,
 | 
				
			||||||
                                 &nd,
 | 
					                  const char    *factory_name,
 | 
				
			||||||
                                 true);
 | 
					                  const char    *name,
 | 
				
			||||||
      break;
 | 
					                  const SpaDict *props,
 | 
				
			||||||
    }
 | 
					                  uint32_t       new_id)
 | 
				
			||||||
    case PINOS_MESSAGE_CREATE_CLIENT_NODE:
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
      PinosMessageCreateClientNode *m = message;
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosClient *client = resource->client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pinos_core_notify_error (client->core_resource,
 | 
				
			||||||
 | 
					                           resource->id,
 | 
				
			||||||
 | 
					                           SPA_RESULT_NOT_IMPLEMENTED,
 | 
				
			||||||
 | 
					                           "not implemented");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					core_create_client_node (void          *object,
 | 
				
			||||||
 | 
					                         uint32_t       seq,
 | 
				
			||||||
 | 
					                         const char    *name,
 | 
				
			||||||
 | 
					                         const SpaDict *props,
 | 
				
			||||||
 | 
					                         uint32_t       new_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PinosResource *resource = object;
 | 
				
			||||||
 | 
					  PinosClient *client = resource->client;
 | 
				
			||||||
  PinosClientNode *node;
 | 
					  PinosClientNode *node;
 | 
				
			||||||
  SpaResult res;
 | 
					  SpaResult res;
 | 
				
			||||||
  int data_fd, i;
 | 
					  int data_fd, i;
 | 
				
			||||||
      PinosMessageCreateClientNodeDone r;
 | 
					  PinosProperties *properties;
 | 
				
			||||||
      PinosProperties *props;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      props = pinos_properties_new (NULL, NULL);
 | 
					  properties = pinos_properties_new (NULL, NULL);
 | 
				
			||||||
      if (props == NULL)
 | 
					  if (properties == NULL)
 | 
				
			||||||
    goto no_mem;
 | 
					    goto no_mem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      for (i = 0; i < m->props->n_items; i++) {
 | 
					  for (i = 0; i < props->n_items; i++) {
 | 
				
			||||||
        pinos_properties_set (props, m->props->items[i].key,
 | 
					    pinos_properties_set (properties, props->items[i].key,
 | 
				
			||||||
                                     m->props->items[i].value);
 | 
					                                      props->items[i].value);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  node = pinos_client_node_new (client,
 | 
					  node = pinos_client_node_new (client,
 | 
				
			||||||
                                    m->new_id,
 | 
					                                new_id,
 | 
				
			||||||
                                    m->name,
 | 
					                                name,
 | 
				
			||||||
                                    props);
 | 
					                                properties);
 | 
				
			||||||
  if (node == NULL)
 | 
					  if (node == NULL)
 | 
				
			||||||
    goto no_mem;
 | 
					    goto no_mem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ((res = pinos_client_node_get_data_socket (node, &data_fd)) < 0) {
 | 
					  if ((res = pinos_client_node_get_data_socket (node, &data_fd)) < 0) {
 | 
				
			||||||
        pinos_client_send_error (client,
 | 
					    pinos_core_notify_error (client->core_resource,
 | 
				
			||||||
                                 resource,
 | 
					                             resource->id,
 | 
				
			||||||
                             SPA_RESULT_ERROR,
 | 
					                             SPA_RESULT_ERROR,
 | 
				
			||||||
                             "can't get data fd");
 | 
					                             "can't get data fd");
 | 
				
			||||||
        break;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      r.seq = m->seq;
 | 
					  pinos_client_node_notify_done (node->resource,
 | 
				
			||||||
      r.datafd = data_fd;
 | 
					                                 seq,
 | 
				
			||||||
      pinos_client_send_message (client,
 | 
					                                 data_fd);
 | 
				
			||||||
                                 node->resource,
 | 
					  return;
 | 
				
			||||||
                                 PINOS_MESSAGE_CREATE_CLIENT_NODE_DONE,
 | 
					 | 
				
			||||||
                                 &r,
 | 
					 | 
				
			||||||
                                 true);
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    default:
 | 
					 | 
				
			||||||
      pinos_log_error ("unhandled message %d", type);
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return SPA_RESULT_OK;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
no_mem:
 | 
					no_mem:
 | 
				
			||||||
  pinos_client_send_error (client,
 | 
					  pinos_core_notify_error (client->core_resource,
 | 
				
			||||||
                           resource,
 | 
					                           resource->id,
 | 
				
			||||||
                           SPA_RESULT_NO_MEMORY,
 | 
					                           SPA_RESULT_NO_MEMORY,
 | 
				
			||||||
                           "no memory");
 | 
					                           "no memory");
 | 
				
			||||||
  return SPA_RESULT_NO_MEMORY;
 | 
					  return;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PinosCoreInterface core_interface = {
 | 
				
			||||||
 | 
					  &core_client_update,
 | 
				
			||||||
 | 
					  &core_sync,
 | 
				
			||||||
 | 
					  &core_get_registry,
 | 
				
			||||||
 | 
					  &core_create_node,
 | 
				
			||||||
 | 
					  &core_create_client_node
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
core_unbind_func (void *data)
 | 
					core_unbind_func (void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -228,8 +226,6 @@ core_bind_func (PinosGlobal *global,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PinosCore *this = global->object;
 | 
					  PinosCore *this = global->object;
 | 
				
			||||||
  PinosResource *resource;
 | 
					  PinosResource *resource;
 | 
				
			||||||
  PinosMessageCoreInfo m;
 | 
					 | 
				
			||||||
  PinosCoreInfo info;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  resource = pinos_resource_new (client,
 | 
					  resource = pinos_resource_new (client,
 | 
				
			||||||
                                 id,
 | 
					                                 id,
 | 
				
			||||||
| 
						 | 
					@ -239,31 +235,18 @@ core_bind_func (PinosGlobal *global,
 | 
				
			||||||
  if (resource == NULL)
 | 
					  if (resource == NULL)
 | 
				
			||||||
    goto no_mem;
 | 
					    goto no_mem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinos_resource_set_dispatch (resource,
 | 
					  resource->interface = &core_interface;
 | 
				
			||||||
                               core_dispatch_func,
 | 
					 | 
				
			||||||
                               this);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  spa_list_insert (this->resource_list.prev, &resource->link);
 | 
					  spa_list_insert (this->resource_list.prev, &resource->link);
 | 
				
			||||||
  client->core_resource = resource;
 | 
					  client->core_resource = resource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinos_log_debug ("core %p: bound to %d", global->object, resource->id);
 | 
					  pinos_log_debug ("core %p: bound to %d", global->object, resource->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  m.info = &info;
 | 
					  this->info.change_mask = PINOS_CORE_CHANGE_MASK_ALL;
 | 
				
			||||||
  info.id = global->id;
 | 
					  pinos_core_notify_info (resource, &this->info);
 | 
				
			||||||
  info.change_mask = PINOS_CORE_CHANGE_MASK_ALL;
 | 
					
 | 
				
			||||||
  info.user_name = pinos_get_user_name ();
 | 
					  return SPA_RESULT_OK;
 | 
				
			||||||
  info.host_name = pinos_get_host_name ();
 | 
					 | 
				
			||||||
  info.version = "0";
 | 
					 | 
				
			||||||
  info.name = "pinos-0";
 | 
					 | 
				
			||||||
  srandom (time (NULL));
 | 
					 | 
				
			||||||
  info.cookie = random ();
 | 
					 | 
				
			||||||
  info.props = this->properties ? &this->properties->dict : NULL;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return pinos_client_send_message (resource->client,
 | 
					 | 
				
			||||||
                                    resource,
 | 
					 | 
				
			||||||
                                    PINOS_MESSAGE_CORE_INFO,
 | 
					 | 
				
			||||||
                                    &m,
 | 
					 | 
				
			||||||
                                    true);
 | 
					 | 
				
			||||||
no_mem:
 | 
					no_mem:
 | 
				
			||||||
  pinos_log_error ("can't create core resource");
 | 
					  pinos_log_error ("can't create core resource");
 | 
				
			||||||
  return SPA_RESULT_NO_MEMORY;
 | 
					  return SPA_RESULT_NO_MEMORY;
 | 
				
			||||||
| 
						 | 
					@ -323,6 +306,16 @@ pinos_core_new (PinosMainLoop   *main_loop,
 | 
				
			||||||
                                        this,
 | 
					                                        this,
 | 
				
			||||||
                                        core_bind_func);
 | 
					                                        core_bind_func);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  this->info.id = this->global->id;
 | 
				
			||||||
 | 
					  this->info.change_mask = 0;
 | 
				
			||||||
 | 
					  this->info.user_name = pinos_get_user_name ();
 | 
				
			||||||
 | 
					  this->info.host_name = pinos_get_host_name ();
 | 
				
			||||||
 | 
					  this->info.version = "0";
 | 
				
			||||||
 | 
					  this->info.name = "pinos-0";
 | 
				
			||||||
 | 
					  srandom (time (NULL));
 | 
				
			||||||
 | 
					  this->info.cookie = random ();
 | 
				
			||||||
 | 
					  this->info.props = this->properties ? &this->properties->dict : NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return this;
 | 
					  return this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
no_data_loop:
 | 
					no_data_loop:
 | 
				
			||||||
| 
						 | 
					@ -357,7 +350,7 @@ pinos_core_add_global (PinosCore     *core,
 | 
				
			||||||
  PinosGlobalImpl *impl;
 | 
					  PinosGlobalImpl *impl;
 | 
				
			||||||
  PinosGlobal *this;
 | 
					  PinosGlobal *this;
 | 
				
			||||||
  PinosResource *registry;
 | 
					  PinosResource *registry;
 | 
				
			||||||
  PinosMessageNotifyGlobal ng;
 | 
					  const char *type_uri;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  impl = calloc (1, sizeof (PinosGlobalImpl));
 | 
					  impl = calloc (1, sizeof (PinosGlobalImpl));
 | 
				
			||||||
  if (impl == NULL)
 | 
					  if (impl == NULL)
 | 
				
			||||||
| 
						 | 
					@ -379,18 +372,14 @@ pinos_core_add_global (PinosCore     *core,
 | 
				
			||||||
  spa_list_insert (core->global_list.prev, &this->link);
 | 
					  spa_list_insert (core->global_list.prev, &this->link);
 | 
				
			||||||
  pinos_signal_emit (&core->global_added, core, this);
 | 
					  pinos_signal_emit (&core->global_added, core, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ng.id = this->id;
 | 
					  type_uri = spa_id_map_get_uri (core->uri.map, this->type);
 | 
				
			||||||
  ng.type = spa_id_map_get_uri (core->uri.map, this->type);
 | 
					  pinos_log_debug ("global %p: new %u %s", this, this->id, type_uri);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinos_log_debug ("global %p: new %u %s", this, ng.id, ng.type);
 | 
					  spa_list_for_each (registry, &core->registry_resource_list, link)
 | 
				
			||||||
 | 
					    pinos_registry_notify_global (registry,
 | 
				
			||||||
 | 
					                                  this->id,
 | 
				
			||||||
 | 
					                                  type_uri);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  spa_list_for_each (registry, &core->registry_resource_list, link) {
 | 
					 | 
				
			||||||
    pinos_client_send_message (registry->client,
 | 
					 | 
				
			||||||
                               registry,
 | 
					 | 
				
			||||||
                               PINOS_MESSAGE_NOTIFY_GLOBAL,
 | 
					 | 
				
			||||||
                               &ng,
 | 
					 | 
				
			||||||
                               true);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return this;
 | 
					  return this;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -404,12 +393,11 @@ pinos_global_bind (PinosGlobal   *global,
 | 
				
			||||||
  PinosGlobalImpl *impl = SPA_CONTAINER_OF (global, PinosGlobalImpl, this);
 | 
					  PinosGlobalImpl *impl = SPA_CONTAINER_OF (global, PinosGlobalImpl, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (impl->bind) {
 | 
					  if (impl->bind) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    res = impl->bind (global, client, version, id);
 | 
					    res = impl->bind (global, client, version, id);
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    res = SPA_RESULT_NOT_IMPLEMENTED;
 | 
					    res = SPA_RESULT_NOT_IMPLEMENTED;
 | 
				
			||||||
    pinos_client_send_error (client,
 | 
					    pinos_core_notify_error (client->core_resource,
 | 
				
			||||||
                             client->core_resource,
 | 
					                             client->core_resource->id,
 | 
				
			||||||
                             res,
 | 
					                             res,
 | 
				
			||||||
                             "can't bind object id %d", id);
 | 
					                             "can't bind object id %d", id);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -421,19 +409,12 @@ pinos_global_destroy (PinosGlobal *global)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PinosCore *core = global->core;
 | 
					  PinosCore *core = global->core;
 | 
				
			||||||
  PinosResource *registry;
 | 
					  PinosResource *registry;
 | 
				
			||||||
  PinosMessageNotifyGlobalRemove ng;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinos_log_debug ("global %p: destroy %u", global, global->id);
 | 
					  pinos_log_debug ("global %p: destroy %u", global, global->id);
 | 
				
			||||||
  pinos_signal_emit (&global->destroy_signal, global);
 | 
					  pinos_signal_emit (&global->destroy_signal, global);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ng.id = global->id;
 | 
					  spa_list_for_each (registry, &core->registry_resource_list, link)
 | 
				
			||||||
  spa_list_for_each (registry, &core->registry_resource_list, link) {
 | 
					    pinos_registry_notify_global_remove (registry, global->id);
 | 
				
			||||||
    pinos_client_send_message (registry->client,
 | 
					 | 
				
			||||||
                               registry,
 | 
					 | 
				
			||||||
                               PINOS_MESSAGE_NOTIFY_GLOBAL_REMOVE,
 | 
					 | 
				
			||||||
                               &ng,
 | 
					 | 
				
			||||||
                               true);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinos_map_remove (&core->objects, global->id);
 | 
					  pinos_map_remove (&core->objects, global->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -448,8 +429,6 @@ void
 | 
				
			||||||
pinos_core_update_properties (PinosCore     *core,
 | 
					pinos_core_update_properties (PinosCore     *core,
 | 
				
			||||||
                              const SpaDict *dict)
 | 
					                              const SpaDict *dict)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PinosMessageCoreInfo m;
 | 
					 | 
				
			||||||
  PinosCoreInfo info;
 | 
					 | 
				
			||||||
  PinosResource *resource;
 | 
					  PinosResource *resource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (core->properties == NULL) {
 | 
					  if (core->properties == NULL) {
 | 
				
			||||||
| 
						 | 
					@ -464,17 +443,11 @@ pinos_core_update_properties (PinosCore     *core,
 | 
				
			||||||
                            dict->items[i].value);
 | 
					                            dict->items[i].value);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  m.info = &info;
 | 
					  core->info.change_mask = PINOS_CORE_CHANGE_MASK_PROPS;
 | 
				
			||||||
  info.id = core->global->id;
 | 
					  core->info.props = core->properties ? &core->properties->dict : NULL;
 | 
				
			||||||
  info.change_mask = PINOS_CORE_CHANGE_MASK_PROPS;
 | 
					 | 
				
			||||||
  info.props = core->properties ? &core->properties->dict : NULL;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  spa_list_for_each (resource, &core->resource_list, link) {
 | 
					  spa_list_for_each (resource, &core->resource_list, link) {
 | 
				
			||||||
    pinos_client_send_message (resource->client,
 | 
					    pinos_core_notify_info (resource, &core->info);
 | 
				
			||||||
                               resource,
 | 
					 | 
				
			||||||
                               PINOS_MESSAGE_CORE_INFO,
 | 
					 | 
				
			||||||
                               &m,
 | 
					 | 
				
			||||||
                               true);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,6 +64,8 @@ struct _PinosGlobal {
 | 
				
			||||||
struct _PinosCore {
 | 
					struct _PinosCore {
 | 
				
			||||||
  PinosGlobal *global;
 | 
					  PinosGlobal *global;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  PinosCoreInfo info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  PinosProperties *properties;
 | 
					  PinosProperties *properties;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  PinosURI uri;
 | 
					  PinosURI uri;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,7 @@
 | 
				
			||||||
#include <spa/lib/debug.h>
 | 
					#include <spa/lib/debug.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pinos/client/pinos.h"
 | 
					#include "pinos/client/pinos.h"
 | 
				
			||||||
 | 
					#include "pinos/client/interfaces.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pinos/server/link.h"
 | 
					#include "pinos/server/link.h"
 | 
				
			||||||
#include "pinos/server/work-queue.h"
 | 
					#include "pinos/server/work-queue.h"
 | 
				
			||||||
| 
						 | 
					@ -693,19 +694,6 @@ pinos_pinos_link_deactivate (PinosLink *this)
 | 
				
			||||||
  return true;
 | 
					  return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static SpaResult
 | 
					 | 
				
			||||||
link_dispatch_func (void             *object,
 | 
					 | 
				
			||||||
                    PinosMessageType  type,
 | 
					 | 
				
			||||||
                    void             *message,
 | 
					 | 
				
			||||||
                    void             *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  switch (type) {
 | 
					 | 
				
			||||||
    default:
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return SPA_RESULT_OK;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
pinos_link_free (PinosLink *link)
 | 
					pinos_link_free (PinosLink *link)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -744,7 +732,6 @@ link_bind_func (PinosGlobal *global,
 | 
				
			||||||
  PinosLink *this = global->object;
 | 
					  PinosLink *this = global->object;
 | 
				
			||||||
  PinosLinkImpl *impl = SPA_CONTAINER_OF (this, PinosLinkImpl, this);
 | 
					  PinosLinkImpl *impl = SPA_CONTAINER_OF (this, PinosLinkImpl, this);
 | 
				
			||||||
  PinosResource *resource;
 | 
					  PinosResource *resource;
 | 
				
			||||||
  PinosMessageLinkInfo m;
 | 
					 | 
				
			||||||
  PinosLinkInfo info;
 | 
					  PinosLinkInfo info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  resource = pinos_resource_new (client,
 | 
					  resource = pinos_resource_new (client,
 | 
				
			||||||
| 
						 | 
					@ -757,15 +744,10 @@ link_bind_func (PinosGlobal *global,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  impl->refcount++;
 | 
					  impl->refcount++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinos_resource_set_dispatch (resource,
 | 
					 | 
				
			||||||
                               link_dispatch_func,
 | 
					 | 
				
			||||||
                               global);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  pinos_log_debug ("link %p: bound to %d", global->object, resource->id);
 | 
					  pinos_log_debug ("link %p: bound to %d", global->object, resource->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  spa_list_insert (this->resource_list.prev, &resource->link);
 | 
					  spa_list_insert (this->resource_list.prev, &resource->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  m.info = &info;
 | 
					 | 
				
			||||||
  info.id = global->id;
 | 
					  info.id = global->id;
 | 
				
			||||||
  info.change_mask = ~0;
 | 
					  info.change_mask = ~0;
 | 
				
			||||||
  info.output_node_id = this->output ? this->output->node->global->id : -1;
 | 
					  info.output_node_id = this->output ? this->output->node->global->id : -1;
 | 
				
			||||||
| 
						 | 
					@ -773,14 +755,13 @@ link_bind_func (PinosGlobal *global,
 | 
				
			||||||
  info.input_node_id = this->input ? this->input->node->global->id : -1;
 | 
					  info.input_node_id = this->input ? this->input->node->global->id : -1;
 | 
				
			||||||
  info.input_port_id = this->input ? this->input->port_id : -1;
 | 
					  info.input_port_id = this->input ? this->input->port_id : -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return pinos_client_send_message (resource->client,
 | 
					  pinos_link_notify_info (resource, &info);
 | 
				
			||||||
                                    resource,
 | 
					
 | 
				
			||||||
                                    PINOS_MESSAGE_LINK_INFO,
 | 
					  return SPA_RESULT_OK;
 | 
				
			||||||
                                    &m,
 | 
					
 | 
				
			||||||
                                    true);
 | 
					 | 
				
			||||||
no_mem:
 | 
					no_mem:
 | 
				
			||||||
  pinos_client_send_error (client,
 | 
					  pinos_core_notify_error (client->core_resource,
 | 
				
			||||||
                           client->core_resource,
 | 
					                           client->core_resource->id,
 | 
				
			||||||
                           SPA_RESULT_NO_MEMORY,
 | 
					                           SPA_RESULT_NO_MEMORY,
 | 
				
			||||||
                           "no memory");
 | 
					                           "no memory");
 | 
				
			||||||
  return SPA_RESULT_NO_MEMORY;
 | 
					  return SPA_RESULT_NO_MEMORY;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pinos/client/pinos.h"
 | 
					#include "pinos/client/pinos.h"
 | 
				
			||||||
 | 
					#include "pinos/client/interfaces.h"
 | 
				
			||||||
#include "pinos/client/utils.h"
 | 
					#include "pinos/client/utils.h"
 | 
				
			||||||
#include "pinos/server/module.h"
 | 
					#include "pinos/server/module.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,7 +38,6 @@
 | 
				
			||||||
typedef struct
 | 
					typedef struct
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PinosModule this;
 | 
					  PinosModule this;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  void *hnd;
 | 
					  void *hnd;
 | 
				
			||||||
} PinosModuleImpl;
 | 
					} PinosModuleImpl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -90,23 +90,6 @@ find_module (const char * path, const char *name)
 | 
				
			||||||
  return filename;
 | 
					  return filename;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static SpaResult
 | 
					 | 
				
			||||||
module_dispatch_func (void             *object,
 | 
					 | 
				
			||||||
                      PinosMessageType  type,
 | 
					 | 
				
			||||||
                      void             *message,
 | 
					 | 
				
			||||||
                      void             *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PinosResource *resource = object;
 | 
					 | 
				
			||||||
  PinosModule *module = resource->object;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  switch (type) {
 | 
					 | 
				
			||||||
    default:
 | 
					 | 
				
			||||||
      pinos_log_warn ("module %p: unhandled message %d", module, type);
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return SPA_RESULT_OK;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static SpaResult
 | 
					static SpaResult
 | 
				
			||||||
module_bind_func (PinosGlobal *global,
 | 
					module_bind_func (PinosGlobal *global,
 | 
				
			||||||
                  PinosClient *client,
 | 
					                  PinosClient *client,
 | 
				
			||||||
| 
						 | 
					@ -115,8 +98,6 @@ module_bind_func (PinosGlobal *global,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PinosModule *this = global->object;
 | 
					  PinosModule *this = global->object;
 | 
				
			||||||
  PinosResource *resource;
 | 
					  PinosResource *resource;
 | 
				
			||||||
  PinosMessageModuleInfo m;
 | 
					 | 
				
			||||||
  PinosModuleInfo info;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  resource = pinos_resource_new (client,
 | 
					  resource = pinos_resource_new (client,
 | 
				
			||||||
                                 id,
 | 
					                                 id,
 | 
				
			||||||
| 
						 | 
					@ -126,28 +107,16 @@ module_bind_func (PinosGlobal *global,
 | 
				
			||||||
  if (resource == NULL)
 | 
					  if (resource == NULL)
 | 
				
			||||||
    goto no_mem;
 | 
					    goto no_mem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinos_resource_set_dispatch (resource,
 | 
					 | 
				
			||||||
                               module_dispatch_func,
 | 
					 | 
				
			||||||
                               global);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  pinos_log_debug ("module %p: bound to %d", global->object, resource->id);
 | 
					  pinos_log_debug ("module %p: bound to %d", global->object, resource->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  m.info = &info;
 | 
					  this->info.change_mask = ~0;
 | 
				
			||||||
  info.id = global->id;
 | 
					  pinos_module_notify_info (resource, &this->info);
 | 
				
			||||||
  info.change_mask = ~0;
 | 
					
 | 
				
			||||||
  info.name = this->name;
 | 
					  return SPA_RESULT_OK;
 | 
				
			||||||
  info.filename = this->filename;
 | 
					 | 
				
			||||||
  info.args = this->args;
 | 
					 | 
				
			||||||
  info.props = NULL;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return pinos_client_send_message (client,
 | 
					 | 
				
			||||||
                                    resource,
 | 
					 | 
				
			||||||
                                    PINOS_MESSAGE_MODULE_INFO,
 | 
					 | 
				
			||||||
                                    &m,
 | 
					 | 
				
			||||||
                                    true);
 | 
					 | 
				
			||||||
no_mem:
 | 
					no_mem:
 | 
				
			||||||
  pinos_client_send_error (client,
 | 
					  pinos_core_notify_error (client->core_resource,
 | 
				
			||||||
                           client->core_resource,
 | 
					                           client->core_resource->id,
 | 
				
			||||||
                           SPA_RESULT_NO_MEMORY,
 | 
					                           SPA_RESULT_NO_MEMORY,
 | 
				
			||||||
                           "no memory");
 | 
					                           "no memory");
 | 
				
			||||||
  return SPA_RESULT_NO_MEMORY;
 | 
					  return SPA_RESULT_NO_MEMORY;
 | 
				
			||||||
| 
						 | 
					@ -217,16 +186,11 @@ pinos_module_load (PinosCore    *core,
 | 
				
			||||||
  impl->hnd = hnd;
 | 
					  impl->hnd = hnd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  this = &impl->this;
 | 
					  this = &impl->this;
 | 
				
			||||||
  this->name = name ? strdup (name) : NULL;
 | 
					 | 
				
			||||||
  this->filename = filename;
 | 
					 | 
				
			||||||
  this->args = args ? strdup (args) : NULL;
 | 
					 | 
				
			||||||
  this->core = core;
 | 
					  this->core = core;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!init_func (this, (char *) args))
 | 
					  if (!init_func (this, (char *) args))
 | 
				
			||||||
    goto init_failed;
 | 
					    goto init_failed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinos_log_debug ("loaded module: %s", this->name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  this->global = pinos_core_add_global (core,
 | 
					  this->global = pinos_core_add_global (core,
 | 
				
			||||||
                                        NULL,
 | 
					                                        NULL,
 | 
				
			||||||
                                        core->uri.module,
 | 
					                                        core->uri.module,
 | 
				
			||||||
| 
						 | 
					@ -234,6 +198,14 @@ pinos_module_load (PinosCore    *core,
 | 
				
			||||||
                                        impl,
 | 
					                                        impl,
 | 
				
			||||||
                                        module_bind_func);
 | 
					                                        module_bind_func);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  this->info.id = this->global->id;
 | 
				
			||||||
 | 
					  this->info.name = name ? strdup (name) : NULL;
 | 
				
			||||||
 | 
					  this->info.filename = filename;
 | 
				
			||||||
 | 
					  this->info.args = args ? strdup (args) : NULL;
 | 
				
			||||||
 | 
					  this->info.props = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pinos_log_debug ("loaded module: %s", this->info.name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return this;
 | 
					  return this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
not_found:
 | 
					not_found:
 | 
				
			||||||
| 
						 | 
					@ -270,12 +242,12 @@ pinos_module_destroy (PinosModule *this)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinos_signal_emit (&this->destroy_signal, this);
 | 
					  pinos_signal_emit (&this->destroy_signal, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (this->name)
 | 
					  if (this->info.name)
 | 
				
			||||||
    free (this->name);
 | 
					    free ((char*)this->info.name);
 | 
				
			||||||
  if (this->filename)
 | 
					  if (this->info.filename)
 | 
				
			||||||
    free (this->filename);
 | 
					    free ((char*)this->info.filename);
 | 
				
			||||||
  if (this->args)
 | 
					  if (this->info.args)
 | 
				
			||||||
    free (this->args);
 | 
					    free ((char*)this->info.args);
 | 
				
			||||||
  dlclose (impl->hnd);
 | 
					  dlclose (impl->hnd);
 | 
				
			||||||
  free (impl);
 | 
					  free (impl);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,9 +34,7 @@ struct _PinosModule {
 | 
				
			||||||
  SpaList      link;
 | 
					  SpaList      link;
 | 
				
			||||||
  PinosGlobal *global;
 | 
					  PinosGlobal *global;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  char *name;
 | 
					  PinosModuleInfo info;
 | 
				
			||||||
  char *filename;
 | 
					 | 
				
			||||||
  char *args;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void *user_data;
 | 
					  void *user_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,6 +22,7 @@
 | 
				
			||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pinos/client/pinos.h"
 | 
					#include "pinos/client/pinos.h"
 | 
				
			||||||
 | 
					#include "pinos/client/interfaces.h"
 | 
				
			||||||
#include "pinos/client/serialize.h"
 | 
					#include "pinos/client/serialize.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pinos/server/node.h"
 | 
					#include "pinos/server/node.h"
 | 
				
			||||||
| 
						 | 
					@ -366,24 +367,6 @@ 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
 | 
					static void
 | 
				
			||||||
node_unbind_func (void *data)
 | 
					node_unbind_func (void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -399,7 +382,6 @@ node_bind_func (PinosGlobal *global,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PinosNode *this = global->object;
 | 
					  PinosNode *this = global->object;
 | 
				
			||||||
  PinosResource *resource;
 | 
					  PinosResource *resource;
 | 
				
			||||||
  PinosMessageNodeInfo m;
 | 
					 | 
				
			||||||
  PinosNodeInfo info;
 | 
					  PinosNodeInfo info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  resource = pinos_resource_new (client,
 | 
					  resource = pinos_resource_new (client,
 | 
				
			||||||
| 
						 | 
					@ -410,15 +392,10 @@ node_bind_func (PinosGlobal *global,
 | 
				
			||||||
  if (resource == NULL)
 | 
					  if (resource == NULL)
 | 
				
			||||||
    goto no_mem;
 | 
					    goto no_mem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinos_resource_set_dispatch (resource,
 | 
					 | 
				
			||||||
                               node_dispatch_func,
 | 
					 | 
				
			||||||
                               global);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  pinos_log_debug ("node %p: bound to %d", this, resource->id);
 | 
					  pinos_log_debug ("node %p: bound to %d", this, resource->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  spa_list_insert (this->resource_list.prev, &resource->link);
 | 
					  spa_list_insert (this->resource_list.prev, &resource->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  m.info = &info;
 | 
					 | 
				
			||||||
  info.id = global->id;
 | 
					  info.id = global->id;
 | 
				
			||||||
  info.change_mask = ~0;
 | 
					  info.change_mask = ~0;
 | 
				
			||||||
  info.name = this->name;
 | 
					  info.name = this->name;
 | 
				
			||||||
| 
						 | 
					@ -466,14 +443,13 @@ node_bind_func (PinosGlobal *global,
 | 
				
			||||||
  info.error = this->error;
 | 
					  info.error = this->error;
 | 
				
			||||||
  info.props = this->properties ? &this->properties->dict : NULL;
 | 
					  info.props = this->properties ? &this->properties->dict : NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return pinos_client_send_message (client,
 | 
					  pinos_node_notify_info (resource, &info);
 | 
				
			||||||
                                    resource,
 | 
					
 | 
				
			||||||
                                    PINOS_MESSAGE_NODE_INFO,
 | 
					  return SPA_RESULT_OK;
 | 
				
			||||||
                                    &m,
 | 
					
 | 
				
			||||||
                                    true);
 | 
					 | 
				
			||||||
no_mem:
 | 
					no_mem:
 | 
				
			||||||
  pinos_client_send_error (client,
 | 
					  pinos_core_notify_error (client->core_resource,
 | 
				
			||||||
                           client->core_resource,
 | 
					                           client->core_resource->id,
 | 
				
			||||||
                           SPA_RESULT_NO_MEMORY,
 | 
					                           SPA_RESULT_NO_MEMORY,
 | 
				
			||||||
                           "no memory");
 | 
					                           "no memory");
 | 
				
			||||||
  return SPA_RESULT_NO_MEMORY;
 | 
					  return SPA_RESULT_NO_MEMORY;
 | 
				
			||||||
| 
						 | 
					@ -828,7 +804,6 @@ pinos_node_update_state (PinosNode      *node,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  old = node->state;
 | 
					  old = node->state;
 | 
				
			||||||
  if (old != state) {
 | 
					  if (old != state) {
 | 
				
			||||||
    PinosMessageNodeInfo m;
 | 
					 | 
				
			||||||
    PinosNodeInfo info;
 | 
					    PinosNodeInfo info;
 | 
				
			||||||
    PinosResource *resource;
 | 
					    PinosResource *resource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -844,18 +819,14 @@ pinos_node_update_state (PinosNode      *node,
 | 
				
			||||||
    pinos_signal_emit (&node->state_changed, node, old, state);
 | 
					    pinos_signal_emit (&node->state_changed, node, old, state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    spa_zero (info);
 | 
					    spa_zero (info);
 | 
				
			||||||
    m.info = &info;
 | 
					 | 
				
			||||||
    info.change_mask = 1 << 5;
 | 
					    info.change_mask = 1 << 5;
 | 
				
			||||||
    info.state = node->state;
 | 
					    info.state = node->state;
 | 
				
			||||||
    info.error = node->error;
 | 
					    info.error = node->error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    spa_list_for_each (resource, &node->resource_list, link) {
 | 
					    spa_list_for_each (resource, &node->resource_list, link) {
 | 
				
			||||||
 | 
					      /* global is only set when there are resources */
 | 
				
			||||||
      info.id = node->global->id;
 | 
					      info.id = node->global->id;
 | 
				
			||||||
      pinos_client_send_message (resource->client,
 | 
					      pinos_node_notify_info (resource, &info);
 | 
				
			||||||
                                 resource,
 | 
					 | 
				
			||||||
                                 PINOS_MESSAGE_NODE_INFO,
 | 
					 | 
				
			||||||
                                 &m,
 | 
					 | 
				
			||||||
                                 true);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,6 +19,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "pinos/client/interfaces.h"
 | 
				
			||||||
#include "pinos/server/resource.h"
 | 
					#include "pinos/server/resource.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
| 
						 | 
					@ -77,83 +78,9 @@ pinos_resource_destroy (PinosResource *resource)
 | 
				
			||||||
  if (resource->destroy)
 | 
					  if (resource->destroy)
 | 
				
			||||||
    resource->destroy (resource);
 | 
					    resource->destroy (resource);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (client->core_resource) {
 | 
					  if (client->core_resource)
 | 
				
			||||||
    PinosMessageRemoveId m;
 | 
					    pinos_core_notify_remove_id (client->core_resource, resource->id);
 | 
				
			||||||
    m.id = resource->id;
 | 
					 | 
				
			||||||
    pinos_client_send_message (client,
 | 
					 | 
				
			||||||
                               client->core_resource,
 | 
					 | 
				
			||||||
                               PINOS_MESSAGE_REMOVE_ID,
 | 
					 | 
				
			||||||
                               &m,
 | 
					 | 
				
			||||||
                               true);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinos_log_debug ("resource %p: free", resource);
 | 
					  pinos_log_debug ("resource %p: free", resource);
 | 
				
			||||||
  free (resource);
 | 
					  free (resource);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
pinos_resource_set_dispatch (PinosResource     *resource,
 | 
					 | 
				
			||||||
                             PinosDispatchFunc  func,
 | 
					 | 
				
			||||||
                             void              *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PinosResourceImpl *impl = SPA_CONTAINER_OF (resource, PinosResourceImpl, this);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  impl->dispatch_func = func;
 | 
					 | 
				
			||||||
  impl->dispatch_data = data;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static SpaResult
 | 
					 | 
				
			||||||
do_dispatch_message (PinosAccessData *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PinosResourceImpl *impl = SPA_CONTAINER_OF (data->resource, PinosResourceImpl, this);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (data->res == SPA_RESULT_NO_PERMISSION) {
 | 
					 | 
				
			||||||
    pinos_client_send_error (data->client,
 | 
					 | 
				
			||||||
                             data->resource,
 | 
					 | 
				
			||||||
                             data->res,
 | 
					 | 
				
			||||||
                             "no permission");
 | 
					 | 
				
			||||||
  } else if (SPA_RESULT_IS_ERROR (data->res)) {
 | 
					 | 
				
			||||||
    pinos_client_send_error (data->client,
 | 
					 | 
				
			||||||
                             data->resource,
 | 
					 | 
				
			||||||
                             data->res,
 | 
					 | 
				
			||||||
                             "error %d", data->res);
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    data->res = impl->dispatch_func (data->resource,
 | 
					 | 
				
			||||||
                                     data->opcode,
 | 
					 | 
				
			||||||
                                     data->message,
 | 
					 | 
				
			||||||
                                     impl->dispatch_data);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return data->res;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
SpaResult
 | 
					 | 
				
			||||||
pinos_resource_dispatch (PinosResource *resource,
 | 
					 | 
				
			||||||
                         uint32_t       opcode,
 | 
					 | 
				
			||||||
                         void          *message)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PinosResourceImpl *impl = SPA_CONTAINER_OF (resource, PinosResourceImpl, this);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (impl->dispatch_func) {
 | 
					 | 
				
			||||||
    PinosAccessData data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    data.client = resource->client;
 | 
					 | 
				
			||||||
    data.resource = resource;
 | 
					 | 
				
			||||||
    data.opcode = opcode;
 | 
					 | 
				
			||||||
    data.message = message;
 | 
					 | 
				
			||||||
    data.flush = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    data.res = SPA_RESULT_OK;
 | 
					 | 
				
			||||||
    pinos_signal_emit (&resource->core->access.check_dispatch,
 | 
					 | 
				
			||||||
                       do_dispatch_message,
 | 
					 | 
				
			||||||
                       &data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (SPA_RESULT_IS_ASYNC (data.res))
 | 
					 | 
				
			||||||
      return data.res;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return do_dispatch_message (&data);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  pinos_log_error ("resource %p: dispatch func not implemented", resource);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return SPA_RESULT_NOT_IMPLEMENTED;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,11 +37,6 @@ typedef struct _PinosResource PinosResource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef void  (*PinosDestroy)  (void *object);
 | 
					typedef void  (*PinosDestroy)  (void *object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef SpaResult (*PinosDispatchFunc) (void             *object,
 | 
					 | 
				
			||||||
                                        uint32_t          opcode,
 | 
					 | 
				
			||||||
                                        void             *message,
 | 
					 | 
				
			||||||
                                        void             *data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct _PinosResource {
 | 
					struct _PinosResource {
 | 
				
			||||||
  PinosCore    *core;
 | 
					  PinosCore    *core;
 | 
				
			||||||
  SpaList       link;
 | 
					  SpaList       link;
 | 
				
			||||||
| 
						 | 
					@ -53,6 +48,10 @@ struct _PinosResource {
 | 
				
			||||||
  void         *object;
 | 
					  void         *object;
 | 
				
			||||||
  PinosDestroy  destroy;
 | 
					  PinosDestroy  destroy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const void *interface;
 | 
				
			||||||
 | 
					  const void *event;
 | 
				
			||||||
 | 
					  const void *marshall;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
 | 
					  PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
 | 
				
			||||||
                                 PinosResource *resource));
 | 
					                                 PinosResource *resource));
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -64,14 +63,6 @@ PinosResource * pinos_resource_new                (PinosClient   *client,
 | 
				
			||||||
                                                   PinosDestroy   destroy);
 | 
					                                                   PinosDestroy   destroy);
 | 
				
			||||||
void            pinos_resource_destroy            (PinosResource *resource);
 | 
					void            pinos_resource_destroy            (PinosResource *resource);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void            pinos_resource_set_dispatch       (PinosResource     *resource,
 | 
					 | 
				
			||||||
                                                   PinosDispatchFunc  func,
 | 
					 | 
				
			||||||
                                                   void              *data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
SpaResult       pinos_resource_dispatch           (PinosResource     *resource,
 | 
					 | 
				
			||||||
                                                   uint32_t           opcode,
 | 
					 | 
				
			||||||
                                                   void              *message);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue