librpc
service.h
Go to the documentation of this file.
1 /*
2  * Copyright 2015-2017 Two Pore Guys, Inc.
3  * All rights reserved
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted providing that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
22  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
23  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24  * POSSIBILITY OF SUCH DAMAGE.
25  *
26  */
27 
28 #ifndef LIBRPC_SERVICE_H
29 #define LIBRPC_SERVICE_H
30 
31 #include <rpc/object.h>
32 #include <rpc/connection.h>
33 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 #ifndef __APPLE__
46 #define __unsafe_unretained
47 #endif
48 
55 #define RPC_FUNCTION_STILL_RUNNING ((rpc_object_t)1)
56 
57 #define RPC_DISCOVERABLE_INTERFACE "com.twoporeguys.librpc.Discoverable"
58 #define RPC_INTROSPECTABLE_INTERFACE "com.twoporeguys.librpc.Introspectable"
59 #define RPC_OBSERVABLE_INTERFACE "com.twoporeguys.librpc.Observable"
60 #define RPC_DEFAULT_INTERFACE "com.twoporeguys.librpc.Default"
61 
65 struct rpc_context;
66 
70 struct rpc_instance;
71 
75 typedef struct rpc_context *rpc_context_t;
76 
80 typedef struct rpc_instance *rpc_instance_t;
81 
85 typedef _Nullable rpc_object_t (^rpc_function_t)(void *_Nonnull cookie,
86  _Nonnull rpc_object_t args);
87 
91 typedef _Nullable rpc_object_t (*rpc_function_f)(void *_Nonnull cookie,
92  _Nonnull rpc_object_t args);
93 
97 typedef _Nullable rpc_object_t (^rpc_property_getter_t)(void *_Nonnull cookie);
98 
102 typedef void (^rpc_property_setter_t)(void *_Nonnull cookie,
103  _Nonnull rpc_object_t value);
104 
108 typedef void (^rpc_abort_handler_t)(void);
109 
113 #define RPC_FUNCTION(_fn) \
114  ^(void *_cookie, rpc_object_t _args) { \
115  return ((rpc_object_t)_fn(_cookie, _args)); \
116  }
117 
118 #define RPC_PROPERTY_GETTER(_fn) \
119  ^(void *_cookie) { \
120  return ((rpc_object_t)_fn(_cookie)); \
121  }
122 
123 #define RPC_PROPERTY_SETTER(_fn) \
124  ^(void *_cookie, rpc_object_t _value) { \
125  _fn(_cookie, _value); \
126  }
127 
128 #define RPC_ABORT_HANDLER(_fn, _arg) \
129  ^(void *_cookie) { \
130  _fn(_arg); \
131  }
132 
133 #define RPC_EVENT(_name) \
134  { \
135  .rim_type = RPC_MEMBER_EVENT, \
136  .rim_name = (#_name) \
137  }
138 
142 #define RPC_PROPERTY_RO(_name, _getter) \
143  { \
144  .rim_type = RPC_MEMBER_PROPERTY, \
145  .rim_name = (#_name), \
146  .rim_property = { \
147  .rp_getter = RPC_PROPERTY_GETTER(_getter), \
148  .rp_setter = NULL, \
149  .rp_arg = NULL \
150  } \
151  }
152 
156 #define RPC_PROPERTY_WO(_name, _setter) \
157  { \
158  .rim_type = RPC_MEMBER_PROPERTY, \
159  .rim_name = (#_name), \
160  .rim_property = { \
161  .rp_getter = NULL, \
162  .rp_setter = RPC_PROPERTY_SETTER(_setter), \
163  .rp_arg = NULL \
164  } \
165  }
166 
170 #define RPC_PROPERTY_RW(_name, _getter, _setter) \
171  { \
172  .rim_type = RPC_MEMBER_PROPERTY, \
173  .rim_name = (#_name), \
174  .rim_property = { \
175  .rp_getter = RPC_PROPERTY_GETTER(_getter), \
176  .rp_setter = RPC_PROPERTY_SETTER(_setter), \
177  .rp_arg = NULL \
178  } \
179  }
180 
184 #define RPC_METHOD(_name, _fn) \
185  { \
186  .rim_type = RPC_MEMBER_METHOD, \
187  .rim_name = (#_name), \
188  .rim_method = { \
189  .rm_block = RPC_FUNCTION(_fn), \
190  .rm_arg = NULL \
191  } \
192  }
193 
198 #define RPC_METHOD_BLOCK(_name, _block) \
199  { \
200  .rim_type = RPC_MEMBER_METHOD, \
201  .rim_name = (#_name), \
202  .rim_method = { \
203  .rm_block = (_block), \
204  } \
205  }
206 
207 #define RPC_MEMBER_END {}
208 
213 {
217 };
218 
223 {
224  RPC_PROPERTY_READ = (1 << 0),
225  RPC_PROPERTY_WRITE = (1 << 1),
226 };
227 
228 
233 {
234  __unsafe_unretained _Nonnull rpc_function_t rm_block;
235  void *_Nullable rm_arg;
236 };
237 
242 {
243  __unsafe_unretained _Nullable rpc_property_getter_t rp_getter;
244  __unsafe_unretained _Nullable rpc_property_setter_t rp_setter;
245  void *_Nullable rp_arg;
246  bool rp_notify;
247 };
248 
255  const char *_Nonnull rim_name;
256  enum rpc_if_member_type rim_type;
257  union {
258  struct rpc_if_method rim_method;
259  struct rpc_if_property rim_property;
260  };
261 };
262 
268 _Nonnull rpc_context_t rpc_context_create(void);
269 
275 void rpc_context_free(_Nonnull rpc_context_t context);
276 
284 _Nullable rpc_instance_t rpc_context_find_instance(
285  _Nonnull rpc_context_t context, const char *_Nonnull path);
286 
293 _Nonnull rpc_instance_t rpc_context_get_root(_Nonnull rpc_context_t context);
294 
302 int rpc_context_register_instance(_Nonnull rpc_context_t context,
303  _Nonnull rpc_instance_t instance);
304 
310 void rpc_context_unregister_instance(_Nonnull rpc_context_t context,
311  const char *_Nonnull path);
312 
322 int rpc_context_register_member(_Nonnull rpc_context_t context,
323  const char *_Nullable interface, struct rpc_if_member *_Nonnull m);
324 
335 int rpc_context_register_block(_Nonnull rpc_context_t context,
336  const char *_Nullable interface, const char *_Nonnull name,
337  void *_Nullable arg, _Nonnull rpc_function_t func);
338 
349 int rpc_context_register_func(_Nonnull rpc_context_t context,
350  const char *_Nullable interface, const char *_Nonnull name,
351  void *_Nullable arg, _Nonnull rpc_function_f func);
352 
360 int rpc_context_unregister_member(_Nonnull rpc_context_t context,
361  const char *_Nullable interface, const char *_Nonnull name);
362 
372 void rpc_context_set_pre_call_hook(_Nonnull rpc_context_t context,
373  _Nonnull rpc_function_t fn);
374 
384 void rpc_context_set_post_call_hook(_Nonnull rpc_context_t context,
385  _Nonnull rpc_function_t fn);
386 
394 _Nullable rpc_call_t rpc_context_dispatch_call(_Nonnull rpc_context_t context,
395  const char *_Nonnull name, _Nullable rpc_object_t args);
396 
404 void rpc_context_emit_event(_Nonnull rpc_context_t context,
405  const char *_Nullable path, const char *_Nullable interface,
406  const char *_Nonnull name, _Nonnull rpc_object_t args);
407 
413 void *_Nullable rpc_function_get_arg(void *_Nonnull cookie);
414 
422 _Nonnull rpc_context_t rpc_function_get_context(void *_Nonnull cookie);
423 
430 _Nullable rpc_connection_t rpc_function_get_connection(void *_Nonnull cookie);
431 
438 _Nonnull rpc_instance_t rpc_function_get_instance(void *_Nonnull cookie);
439 
445 const char *_Nonnull rpc_function_get_name(void *_Nonnull cookie);
446 
452 const char *_Nonnull rpc_function_get_path(void *_Nonnull cookie);
453 
459 const char *_Nonnull rpc_function_get_interface(void *_Nonnull cookie);
460 
471 void rpc_function_respond(void *_Nonnull cookie, _Nullable rpc_object_t object);
472 
487 void rpc_function_error(void *_Nonnull cookie, int code,
488  const char *_Nonnull message, ...);
489 
496 void rpc_function_error_ex(void *_Nonnull cookie,
497  _Nonnull rpc_object_t exception);
498 
505 int rpc_function_start_stream(void *_Nonnull cookie);
506 
514 int rpc_function_yield(void *_Nonnull cookie, _Nonnull rpc_object_t fragment);
515 
525 void rpc_function_end(void *_Nonnull cookie);
526 
535 void rpc_function_kill(void *_Nonnull cookie);
536 
544 bool rpc_function_should_abort(void *_Nonnull cookie);
545 
553 void rpc_function_set_async_abort_handler(void *_Nonnull cookie,
554  _Nullable rpc_abort_handler_t handler);
555 
565 int rpc_function_retain(void *_Nonnull cookie);
566 
575 int rpc_function_release(void *_Nonnull cookie);
576 
584 _Nullable rpc_instance_t rpc_instance_new(void *_Nullable arg,
585  const char *_Nonnull fmt, ...);
586 
594 void rpc_instance_set_description(_Nonnull rpc_instance_t instance,
595  const char *_Nonnull fmt, ...);
596 
603 void *_Nullable rpc_instance_get_arg(_Nonnull rpc_instance_t instance);
604 
611 const char *_Nonnull rpc_instance_get_path(_Nonnull rpc_instance_t instance);
612 
622 int rpc_instance_register_interface(_Nonnull rpc_instance_t instance,
623  const char *_Nonnull interface,
624  const struct rpc_if_member *_Nullable vtable, void *_Nullable arg);
625 
633 void rpc_instance_unregister_interface(_Nonnull rpc_instance_t instance,
634  const char *_Nonnull interface);
635 
644 int rpc_instance_register_member(_Nonnull rpc_instance_t instance,
645  const char *_Nonnull interface,
646  const struct rpc_if_member *_Nonnull member);
647 
657 int rpc_instance_unregister_member(_Nonnull rpc_instance_t instance,
658  const char *_Nonnull interface, const char *_Nonnull name);
659 
671 int rpc_instance_register_block(_Nonnull rpc_instance_t instance,
672  const char *_Nonnull interface, const char *_Nonnull name,
673  void *_Nullable arg, _Nonnull rpc_function_t fn);
674 
685 int rpc_instance_register_func(_Nonnull rpc_instance_t instance,
686  const char *_Nonnull interface, const char *_Nonnull name,
687  void *_Nullable arg, _Nonnull rpc_function_f fn);
688 
697 struct rpc_if_member *_Nullable rpc_instance_find_member(
698  _Nonnull rpc_instance_t instance, const char *_Nullable interface,
699  const char *_Nonnull name);
700 
708 bool rpc_instance_has_interface(_Nonnull rpc_instance_t instance,
709  const char *_Nonnull interface);
710 
717 void rpc_instance_emit_event(_Nonnull rpc_instance_t instance,
718  const char *_Nonnull interface, const char *_Nonnull name,
719  _Nonnull rpc_object_t args);
720 
738 int rpc_instance_register_property(_Nonnull rpc_instance_t instance,
739  const char *_Nonnull interface, const char *_Nonnull name,
740  void *_Nullable arg, _Nullable rpc_property_getter_t getter,
741  _Nullable rpc_property_setter_t setter);
742 
752 int rpc_instance_get_property_rights(_Nonnull rpc_instance_t instance,
753  const char *_Nonnull interface, const char *_Nonnull name);
754 
762 int rpc_instance_register_event(_Nonnull rpc_instance_t instance,
763  const char *_Nonnull interface, const char *_Nonnull name);
764 
779 void rpc_instance_property_changed(_Nonnull rpc_instance_t instance,
780  const char *_Nonnull interface, const char *_Nonnull name,
781  _Nullable rpc_object_t value);
782 
789 _Nonnull rpc_instance_t rpc_property_get_instance(void *_Nonnull cookie);
790 
798 void *_Nullable rpc_property_get_arg(void *_Nonnull cookie);
799 
810 void rpc_property_error(void *_Nonnull cookie, int code,
811  const char *_Nonnull fmt, ...);
812 
818 void rpc_instance_free(_Nonnull rpc_instance_t instance);
819 
820 #ifdef __cplusplus
821 }
822 #endif
823 
824 #endif /* LIBRPC_SERVICE_H */
void(^ rpc_property_setter_t)(void *_Nonnull cookie, _Nonnull rpc_object_t value)
Definition: service.h:102
void rpc_function_end(void *_Nonnull cookie)
struct rpc_object * rpc_object_t
Definition: object.h:73
int rpc_context_unregister_member(_Nonnull rpc_context_t context, const char *_Nullable interface, const char *_Nonnull name)
const char *_Nonnull rpc_function_get_interface(void *_Nonnull cookie)
void rpc_instance_set_description(_Nonnull rpc_instance_t instance, const char *_Nonnull fmt,...)
void rpc_property_error(void *_Nonnull cookie, int code, const char *_Nonnull fmt,...)
void rpc_function_kill(void *_Nonnull cookie)
_Nullable rpc_object_t(* rpc_function_f)(void *_Nonnull cookie, _Nonnull rpc_object_t args)
Definition: service.h:91
int rpc_function_start_stream(void *_Nonnull cookie)
void rpc_function_error_ex(void *_Nonnull cookie, _Nonnull rpc_object_t exception)
int rpc_context_register_instance(_Nonnull rpc_context_t context, _Nonnull rpc_instance_t instance)
rpc_if_member_type
Definition: service.h:212
void rpc_context_unregister_instance(_Nonnull rpc_context_t context, const char *_Nonnull path)
struct rpc_instance * rpc_instance_t
Definition: service.h:80
void rpc_instance_free(_Nonnull rpc_instance_t instance)
void(^ rpc_abort_handler_t)(void)
Definition: service.h:108
_Nullable rpc_instance_t rpc_instance_new(void *_Nullable arg, const char *_Nonnull fmt,...)
void rpc_function_set_async_abort_handler(void *_Nonnull cookie, _Nullable rpc_abort_handler_t handler)
const char *_Nonnull rpc_instance_get_path(_Nonnull rpc_instance_t instance)
struct rpc_connection * rpc_connection_t
Definition: connection.h:94
void rpc_instance_emit_event(_Nonnull rpc_instance_t instance, const char *_Nonnull interface, const char *_Nonnull name, _Nonnull rpc_object_t args)
void rpc_function_error(void *_Nonnull cookie, int code, const char *_Nonnull message,...)
int rpc_instance_unregister_member(_Nonnull rpc_instance_t instance, const char *_Nonnull interface, const char *_Nonnull name)
int rpc_function_release(void *_Nonnull cookie)
int rpc_function_retain(void *_Nonnull cookie)
_Nullable rpc_call_t rpc_context_dispatch_call(_Nonnull rpc_context_t context, const char *_Nonnull name, _Nullable rpc_object_t args)
int rpc_instance_register_block(_Nonnull rpc_instance_t instance, const char *_Nonnull interface, const char *_Nonnull name, void *_Nullable arg, _Nonnull rpc_function_t fn)
struct rpc_context * rpc_context_t
Definition: service.h:75
_Nonnull rpc_instance_t rpc_property_get_instance(void *_Nonnull cookie)
void rpc_context_set_post_call_hook(_Nonnull rpc_context_t context, _Nonnull rpc_function_t fn)
_Nullable rpc_object_t(^ rpc_function_t)(void *_Nonnull cookie, _Nonnull rpc_object_t args)
Definition: service.h:85
int rpc_instance_register_property(_Nonnull rpc_instance_t instance, const char *_Nonnull interface, const char *_Nonnull name, void *_Nullable arg, _Nullable rpc_property_getter_t getter, _Nullable rpc_property_setter_t setter)
void *_Nullable rpc_instance_get_arg(_Nonnull rpc_instance_t instance)
bool rpc_instance_has_interface(_Nonnull rpc_instance_t instance, const char *_Nonnull interface)
void rpc_instance_unregister_interface(_Nonnull rpc_instance_t instance, const char *_Nonnull interface)
struct rpc_call * rpc_call_t
Definition: connection.h:99
const char *_Nonnull rpc_function_get_name(void *_Nonnull cookie)
_Nonnull rpc_context_t rpc_context_create(void)
_Nonnull rpc_instance_t rpc_function_get_instance(void *_Nonnull cookie)
bool rpc_function_should_abort(void *_Nonnull cookie)
const char *_Nonnull rpc_function_get_path(void *_Nonnull cookie)
void *_Nullable rpc_function_get_arg(void *_Nonnull cookie)
void rpc_instance_property_changed(_Nonnull rpc_instance_t instance, const char *_Nonnull interface, const char *_Nonnull name, _Nullable rpc_object_t value)
void rpc_context_emit_event(_Nonnull rpc_context_t context, const char *_Nullable path, const char *_Nullable interface, const char *_Nonnull name, _Nonnull rpc_object_t args)
_Nonnull rpc_instance_t rpc_context_get_root(_Nonnull rpc_context_t context)
int rpc_context_register_func(_Nonnull rpc_context_t context, const char *_Nullable interface, const char *_Nonnull name, void *_Nullable arg, _Nonnull rpc_function_f func)
rpc_property_rights
Definition: service.h:222
void rpc_function_respond(void *_Nonnull cookie, _Nullable rpc_object_t object)
void *_Nullable rpc_property_get_arg(void *_Nonnull cookie)
void rpc_context_set_pre_call_hook(_Nonnull rpc_context_t context, _Nonnull rpc_function_t fn)
_Nullable rpc_object_t(^ rpc_property_getter_t)(void *_Nonnull cookie)
Definition: service.h:97
int rpc_instance_register_func(_Nonnull rpc_instance_t instance, const char *_Nonnull interface, const char *_Nonnull name, void *_Nullable arg, _Nonnull rpc_function_f fn)
int rpc_context_register_member(_Nonnull rpc_context_t context, const char *_Nullable interface, struct rpc_if_member *_Nonnull m)
int rpc_instance_register_interface(_Nonnull rpc_instance_t instance, const char *_Nonnull interface, const struct rpc_if_member *_Nullable vtable, void *_Nullable arg)
int rpc_function_yield(void *_Nonnull cookie, _Nonnull rpc_object_t fragment)
int rpc_instance_register_event(_Nonnull rpc_instance_t instance, const char *_Nonnull interface, const char *_Nonnull name)
int rpc_instance_get_property_rights(_Nonnull rpc_instance_t instance, const char *_Nonnull interface, const char *_Nonnull name)
int rpc_instance_register_member(_Nonnull rpc_instance_t instance, const char *_Nonnull interface, const struct rpc_if_member *_Nonnull member)
_Nullable rpc_connection_t rpc_function_get_connection(void *_Nonnull cookie)
int rpc_context_register_block(_Nonnull rpc_context_t context, const char *_Nullable interface, const char *_Nonnull name, void *_Nullable arg, _Nonnull rpc_function_t func)
_Nullable rpc_instance_t rpc_context_find_instance(_Nonnull rpc_context_t context, const char *_Nonnull path)
void rpc_context_free(_Nonnull rpc_context_t context)
_Nonnull rpc_context_t rpc_function_get_context(void *_Nonnull cookie)
struct rpc_if_member *_Nullable rpc_instance_find_member(_Nonnull rpc_instance_t instance, const char *_Nullable interface, const char *_Nonnull name)