libamxd  6.4.1
Data Model Manager
Define RPC methods

Functions

amxd_status_t amxd_function_new (amxd_function_t **func, const char *name, const uint32_t ret_type, amxd_object_fn_t impl)
 Data model RPC method constructor function. More...
 
void amxd_function_delete (amxd_function_t **func)
 Data model RPC method destructor function. More...
 
amxd_status_t amxd_function_copy (amxd_function_t **dest, const amxd_function_t *const source)
 Data model RPC method copy constructor function. More...
 
amxd_object_tamxd_function_get_owner (const amxd_function_t *const func)
 Get the object pointer of the object containing the function definition. More...
 
amxd_function_tamxd_function_get_base (const amxd_function_t *const func)
 Get the base function definition of an overridden function. More...
 
amxd_status_t amxd_function_call_base (const amxd_function_t *const func, amxd_object_t *const object, amxc_var_t *const args, amxc_var_t *const ret)
 Call the base function of an overridden function. More...
 
const char * amxd_function_get_name (const amxd_function_t *const func)
 Get the name of a method. More...
 
static uint32_t amxd_function_get_type (const amxd_function_t *const func)
 Gets the return type of a method. More...
 
amxd_status_t amxd_function_set_attr (amxd_function_t *func, const amxd_fattr_id_t attr, const bool enable)
 Sets or unsets a method attribute. More...
 
amxd_status_t amxd_function_set_attrs (amxd_function_t *func, const uint32_t bitmask, bool enable)
 Sets or unsets method attributes using a bitmap. More...
 
uint32_t amxd_function_get_attrs (const amxd_function_t *const func)
 Gets the set attributes of a RPC method. More...
 
bool amxd_function_is_attr_set (const amxd_function_t *const func, const amxd_fattr_id_t attr)
 Checks if a method attribute is set. More...
 
void amxd_function_set_flag (amxd_function_t *func, const char *flag)
 Sets a flag on a function. More...
 
void amxd_function_unset_flag (amxd_function_t *func, const char *flag)
 Removes a flag from a function. More...
 
bool amxd_function_has_flag (const amxd_function_t *const func, const char *flag)
 Checks if a flag is set. More...
 
amxd_status_t amxd_function_set_impl (amxd_function_t *const func, amxd_object_fn_t impl)
 Set an implementation for a RPC method. More...
 
amxd_status_t amxd_function_describe (amxd_function_t *const func, amxc_var_t *const value)
 Fetches the full RPC method definition in a variant. More...
 
amxd_status_t amxd_function_defer (const amxd_function_t *const func, uint64_t *call_id, amxc_var_t *const ret, amxd_deferred_cancel_t cancel_fn, void *priv)
 Creates a deferred RPC context. More...
 
void amxd_function_deferred_remove (uint64_t call_id)
 Removes a deferred RPC context. More...
 
void * amxd_function_deferred_get_priv (uint64_t call_id)
 Gets the callee private data of an deferred function. More...
 
amxd_status_t amxd_function_set_deferred_cb (uint64_t call_id, amxp_deferred_fn_t cb, void *priv)
 Sets a callback function to get the result of the deferred call. More...
 
amxd_status_t amxd_function_deferred_done (uint64_t call_id, amxd_status_t status, amxc_var_t *out_args, amxc_var_t *ret)
 Finishes a deferred method and removes the deferred function context. More...
 
amxd_status_t amxd_function_deferred_call_done (uint64_t call_id, amxd_status_t status, amxc_var_t *out_args, amxc_var_t *ret)
 Finishes a deferred method and removes the deferred function context. More...
 
amxd_status_t amxd_function_new_arg (amxd_function_t *func, const char *name, const uint32_t type, amxc_var_t *default_value)
 Adds an argument definition to a RPC method definition. More...
 
void amxd_function_del_arg (amxd_function_t *func, const char *name)
 Removes an argument definition from a RPC method definition. More...
 
amxd_func_arg_tamxd_function_get_arg (const amxd_function_t *const func, const char *name)
 Gets the argument definition of a RPC method. More...
 
amxd_status_t amxd_function_arg_set_attr (amxd_function_t *const func, const char *name, const amxd_aattr_id_t attr, const bool enable)
 Sets or unsets a method argument attribute. More...
 
amxd_status_t amxd_function_arg_set_attrs (amxd_function_t *func, const char *name, const uint32_t bitmask, bool enable)
 Sets or unsets method argument attributes using a bitmap. More...
 
bool amxd_function_arg_is_attr_set (const amxd_function_t *const func, const char *name, const amxd_aattr_id_t attr)
 Checks if a method argument attribute is set. More...
 
amxd_status_t amxd_function_arg_describe (amxd_func_arg_t *const arg, amxc_var_t *const value)
 Fetches the argument definition in a variant. More...
 
bool amxd_function_are_args_valid (amxd_function_t *func, amxc_var_t *args)
 Validates that the input arguments are valid. More...
 

Detailed Description

Function Documentation

◆ amxd_function_are_args_valid()

bool amxd_function_are_args_valid ( amxd_function_t func,
amxc_var_t *  args 
)

Validates that the input arguments are valid.

The arguments must be provided as a htable variant, where each argument is an entry in the hash table.

This function will check that:

  1. all mandatory in arguments are provided
  2. all strict typed arguments have the correct type information.

Missing optional arguments with a default value defined will be added to the htable variant.

Note
This function is not validating that the values of each individual argument are valid, it only verifies that all mandatory arguments with the correct type are present in the provided htable variant.
Parameters
funcpointer to a function definition
argsvariant containing a htable with function arguments
Returns
true when the argument hash table is valid. false when the provided arguments are not valid, or NULL pointers are provided for the function definition or arguments variant.

Definition at line 486 of file amxd_function.c.

487  {
488  bool valid = false;
489 
490  when_null(func, exit);
491  when_null(args, exit);
492  when_false(amxc_var_type_of(args) == AMXC_VAR_ID_HTABLE, exit);
493 
494  amxc_llist_for_each(it, (&func->args)) {
495  amxd_func_arg_t* arg = amxc_llist_it_get_data(it, amxd_func_arg_t, it);
496  amxc_var_t* in_arg = amxc_var_get_key(args,
497  arg->name,
498  AMXC_VAR_FLAG_DEFAULT);
499  if(arg->attr.in == 0) {
500  continue;
501  }
502  if(arg->attr.mandatory == 1) {
503  when_null(in_arg, exit);
504  }
505  if((in_arg == NULL) &&
506  ( amxc_var_type_of(&arg->default_value) != AMXC_VAR_ID_NULL)) {
507  in_arg = amxc_var_add_new_key(args, arg->name);
508  amxc_var_copy(in_arg, &arg->default_value);
509  }
510  if((arg->attr.strict == 1) &&
511  ( in_arg != NULL)) {
512  when_true(arg->type != amxc_var_type_of(in_arg), exit);
513  }
514  }
515 
516  valid = true;
517 
518 exit:
519  return valid;
520 }
uint32_t in
Definition: amxd_types.h:291
uint32_t strict
Definition: amxd_types.h:294
uint32_t mandatory
Definition: amxd_types.h:293
amxc_var_t default_value
Definition: amxd_types.h:302
uint32_t type
Definition: amxd_types.h:301
amxd_arg_attr_t attr
Definition: amxd_types.h:299
amxc_llist_t args
Definition: amxd_types.h:346

◆ amxd_function_arg_describe()

amxd_status_t amxd_function_arg_describe ( amxd_func_arg_t *const  arg,
amxc_var_t *const  value 
)

Fetches the argument definition in a variant.

It can be very handy to get the full definition of the argument.

This function is mainly intended for introspection.

Parameters
argpointer to a argument definition
valuevariant where the argument defintion can be stored
Returns
amxd_status_ok when the function implementation is set, or another status when an error has occurred.

Definition at line 278 of file amxd_function_args.c.

279  {
281  amxc_var_t* table = NULL;
282  uint32_t attrs = 0;
283  static const char* attr_name[] = {
284  "in",
285  "out",
286  "mandatory",
287  "strict"
288  };
289 
290  when_null(arg, exit);
291  when_null(value, exit);
292 
293  amxc_var_set_type(value, AMXC_VAR_ID_HTABLE);
294  amxc_var_add_key(cstring_t, value, "name", arg->name);
295  amxc_var_add_key(uint32_t, value, "type_id", arg->type);
296  amxc_var_add_key(cstring_t,
297  value,
298  "type_name",
299  amxc_var_get_type_name_from_id(arg->type));
300  if(!amxc_var_is_null(&arg->default_value)) {
301  amxc_var_set_key(value, "default", &arg->default_value, AMXC_VAR_FLAG_COPY);
302  }
303  table = amxc_var_add_key(amxc_htable_t, value, "attributes", NULL);
305  for(int i = 0; i <= amxd_aattr_max; i++) {
306  bool is_set = (attrs & (1 << i)) != 0 ? true : false;
307  amxc_var_add_key(bool,
308  table,
309  attr_name[i],
310  is_set);
311  }
312 
314 
315 exit:
316  return status;
317 }
static uint32_t amxd_function_arg_get_attributes(const amxd_func_arg_t *const arg)
enum _amxd_status amxd_status_t
@ amxd_status_ok
Definition: amxd_types.h:78
@ amxd_status_unknown_error
Definition: amxd_types.h:79
@ amxd_aattr_max
Definition: amxd_types.h:287
static amxd_status_t status

◆ amxd_function_arg_is_attr_set()

bool amxd_function_arg_is_attr_set ( const amxd_function_t *const  func,
const char *  name,
const amxd_aattr_id_t  attr 
)

Checks if a method argument attribute is set.

The following attribute identifiers can be checked

Parameters
funcpointer to a function definition
namethe argument name
attrthe method attribute id
Returns
Returns true if attribute is set and false when unset

Definition at line 260 of file amxd_function_args.c.

262  {
263  uint32_t flags = 0;
264  amxd_func_arg_t* arg = NULL;
265  bool retval = false;
266  when_null(func, exit);
267  when_true(attr < 0 || attr > amxd_aattr_max, exit);
268 
269  arg = amxd_function_get_arg(func, name);
270  when_null(arg, exit);
272  retval = (flags & (1 << attr)) != 0 ? true : false;
273 
274 exit:
275  return retval;
276 }
amxd_func_arg_t * amxd_function_get_arg(const amxd_function_t *const func, const char *name)
Gets the argument definition of a RPC method.

◆ amxd_function_arg_set_attr()

amxd_status_t amxd_function_arg_set_attr ( amxd_function_t *const  func,
const char *  name,
const amxd_aattr_id_t  attr,
const bool  enable 
)

Sets or unsets a method argument attribute.

The following attributes can be set - unset:

Parameters
funcpointer to a function definition
namethe argument name
attrthe attribute id
enablewhen true, sets the attribute, when false unsets the attribute
Returns
Returns amxd_status_ok when attribute is changed, any other when failed

Definition at line 183 of file amxd_function_args.c.

186  {
188  uint32_t flags = 0;
189  amxd_func_arg_t* arg = NULL;
190  when_null(func, exit);
191 
192  when_true_status(attr < 0 || attr > amxd_aattr_max,
193  exit,
194  retval = amxd_status_invalid_attr);
195 
196  arg = amxd_function_get_arg(func, name);
197  when_null(arg, exit);
199 
200  // when type any is set, it can not be a strict typed argument
201  if((attr == amxd_aattr_strict) &&
202  ( arg->type == AMXC_VAR_ID_ANY)) {
203  retval = amxd_status_invalid_attr;
204  goto exit;
205  }
206 
207  if(enable) {
208  flags |= (1 << attr);
209  } else {
210  flags &= ~(1 << attr);
211  }
212 
214  retval = amxd_status_ok;
215 
216 exit:
217  return retval;
218 }
static void amxd_function_arg_set_attributes(amxd_func_arg_t *const arg, const uint32_t attr)
@ amxd_status_invalid_attr
Definition: amxd_types.h:87
@ amxd_aattr_strict
Definition: amxd_types.h:286

◆ amxd_function_arg_set_attrs()

amxd_status_t amxd_function_arg_set_attrs ( amxd_function_t func,
const char *  name,
const uint32_t  bitmask,
bool  enable 
)

Sets or unsets method argument attributes using a bitmap.

The following attributes can be set - unset:

Use the macro SET_BIT to transform the attribute id to a bit. The bits can be joined together using the bitwise or operator '|'

"number",
true);
#define SET_BIT(x)
Definition: amxd_common.h:65
@ amxd_aattr_in
Definition: amxd_types.h:283
amxd_status_t amxd_function_arg_set_attrs(amxd_function_t *func, const char *name, const uint32_t bitmask, bool enable)
Sets or unsets method argument attributes using a bitmap.

When setting or unsetting one single attribute the function amxd_function_arg_set_attr can be used.

Parameters
funcpointer to a function definition
namethe argument name
bitmaskthe function attribute bitmask
enablewhen true, sets the attributes, when false unsets the attributes
Returns
Returns amxd_status_ok when attributes are changed, any other status when failed

Definition at line 220 of file amxd_function_args.c.

223  {
225  uint32_t flags = 0;
226  amxd_func_arg_t* arg = NULL;
227  uint32_t all = 0;
228 
229  for(int i = 0; i <= amxd_aattr_max; i++) {
230  all |= SET_BIT(i);
231  }
232 
233  when_null(func, exit);
234  when_true_status(bitmask > all, exit, retval = amxd_status_invalid_attr);
235 
236  arg = amxd_function_get_arg(func, name);
237  when_null(arg, exit);
239 
240  // when type any is set, it can not be a strict typed argument
241  if(((bitmask & SET_BIT(amxd_aattr_strict)) != 0) &&
242  ( arg->type == AMXC_VAR_ID_ANY)) {
243  retval = amxd_status_invalid_attr;
244  goto exit;
245  }
246 
247  if(enable) {
248  flags |= bitmask;
249  } else {
250  flags &= ~bitmask;
251  }
252 
254  retval = amxd_status_ok;
255 
256 exit:
257  return retval;
258 }

◆ amxd_function_call_base()

amxd_status_t amxd_function_call_base ( const amxd_function_t *const  func,
amxd_object_t *const  object,
amxc_var_t *const  args,
amxc_var_t *const  ret 
)

Call the base function of an overridden function.

In derived objects it is possible to override methods and set a different implementation. Using this function the base implementation from which the method is derived is called.

Parameters
funcpointer to a function definition
objectthe object on which the function must be called
argshtable variant containing the function arguments
retvariant that can be filled with the function return data
Returns
amxd_status_ok when function was successful, or an other status when an error occured

Definition at line 260 of file amxd_function.c.

263  {
265  amxd_function_t* base_func = amxd_function_get_base(func);
266 
267  when_null(object, exit);
268  when_null(base_func, exit);
269  if(base_func->impl == NULL) {
271  goto exit;
272  }
273  status = base_func->impl(object, base_func, args, ret);
274 
275 exit:
276  return status;
277 }
@ amxd_status_function_not_implemented
Definition: amxd_types.h:83
amxd_function_t * amxd_function_get_base(const amxd_function_t *const func)
Get the base function definition of an overridden function.
RPC method structure.
Definition: amxd_types.h:341
amxd_object_fn_t impl
Definition: amxd_types.h:347

◆ amxd_function_copy()

amxd_status_t amxd_function_copy ( amxd_function_t **  dest,
const amxd_function_t *const  source 
)

Data model RPC method copy constructor function.

Makes an exact deep copy a RPC method definition.

The newly created RPC method definition will not be added to any data model object, that can be done using amxd_object_add_function

Note
Derived objects are always inheriting the methods.
Parameters
destpointer to a pointer to the new RPC method definition (the copy)
sourcepointer to a RPC method definition
Returns
amxd_status_ok when the function definition is created, or another status when an error has occurred.

Definition at line 181 of file amxd_function.c.

182  {
184  when_null(dest, exit);
185  when_null(source, exit);
186 
187  *dest = (amxd_function_t*) calloc(1, sizeof(amxd_function_t));
188  when_null((*dest), exit);
189 
190  when_failed(amxd_function_init(*dest, source->name,
191  source->ret_type,
192  source->impl), exit);
193  (*dest)->attr = source->attr;
194 
195  amxc_llist_for_each(it, (&source->args)) {
196  amxd_func_arg_t* arg = amxc_llist_it_get_data(it, amxd_func_arg_t, it);
197  when_failed(amxd_function_new_arg((*dest),
198  arg->name,
199  arg->type,
200  &arg->default_value), exit);
202  amxd_function_arg_set_attr((*dest), arg->name, amxd_aattr_in, true);
203  }
205  amxd_function_arg_set_attr((*dest), arg->name, amxd_aattr_out, true);
206  }
209  }
211  amxd_function_arg_set_attr((*dest), arg->name, amxd_aattr_strict, true);
212  }
213  }
214 
215  retval = amxd_status_ok;
216 
217 exit:
218  if((retval != amxd_status_ok) && (dest != NULL) && (*dest != NULL)) {
219  amxd_function_clean(*dest);
220  free(*dest);
221  *dest = NULL;
222  }
223  return retval;
224 }
static amxd_status_t amxd_function_init(amxd_function_t *const func, const char *name, uint32_t ret_type, amxd_object_fn_t impl)
Definition: amxd_function.c:83
static int amxd_function_clean(amxd_function_t *const func)
@ amxd_aattr_mandatory
Definition: amxd_types.h:285
@ amxd_aattr_out
Definition: amxd_types.h:284
amxd_status_t amxd_function_arg_set_attr(amxd_function_t *const func, const char *name, const amxd_aattr_id_t attr, const bool enable)
Sets or unsets a method argument attribute.
bool amxd_function_arg_is_attr_set(const amxd_function_t *const func, const char *name, const amxd_aattr_id_t attr)
Checks if a method argument attribute is set.
amxd_status_t amxd_function_new_arg(amxd_function_t *func, const char *name, const uint32_t type, amxc_var_t *default_value)
Adds an argument definition to a RPC method definition.
uint32_t ret_type
Definition: amxd_types.h:345
amxd_func_attr_t attr
Definition: amxd_types.h:343

◆ amxd_function_defer()

amxd_status_t amxd_function_defer ( const amxd_function_t *const  func,
uint64_t *  call_id,
amxc_var_t *const  ret,
amxd_deferred_cancel_t  cancel_fn,
void *  priv 
)

Creates a deferred RPC context.

If an RPC method can take a while before it can return the result, it can reply the result later (ie asynchronous I/O). To indicate the result will be available later, the RPC method must return status amxd_status_deferred and must call this function before returning.

When the result is available (ie asynchronous I/O is done), the method amxd_function_deferred_done must be called.

It is also possible to remove the deferred call by calling amxd_function_deferred_remove. This will send an error back to the caller.

Parameters
funcpointer to a function definition
call_ideach deferred method gets a call_id, it will be filled in this integer. The call_id is needed in all other calls related to deferred RPC methods
retThe call id will also be filled in the return value of the RPC method. This will enable the caller to add a callback function to get informed when the result is available.
cancel_fnOptionally a cancel callback function can be given. This will be called when the deferred function is removed.
privSome private data for the callee, will be provided to the cancel callback function. Typically used to be able to free allocated memory when the deferred function is canceled.
Returns
amxd_status_ok when the deferred context is created or another status when an error has occurred.

Definition at line 126 of file amxd_function_deferred.c.

130  {
132  amxd_deferred_ctx_t* call = NULL;
133 
134  when_null(func, exit);
135  when_null(ret, exit);
136  when_null(call_id, exit)
137 
138  call = (amxd_deferred_ctx_t*) calloc(1, sizeof(amxd_deferred_ctx_t));
139  when_null(call, exit);
140 
141  call->call_id = g_call_id++;
142  call->called_priv = priv;
143  call->cancel = cancel_fn;
144  amxc_llist_append(&deferred, &call->it);
145  amxc_var_set(uint64_t, ret, call->call_id);
146  *call_id = call->call_id;
147 
149 
150 exit:
151  return status;
152 }
static amxc_llist_t deferred
static uint64_t g_call_id
amxc_llist_it_t it
Definition: amxd_dm_priv.h:63
amxd_deferred_cancel_t cancel
Definition: amxd_dm_priv.h:66
static uint64_t call_id

◆ amxd_function_deferred_call_done()

amxd_status_t amxd_function_deferred_call_done ( uint64_t  call_id,
amxd_status_t  status,
amxc_var_t *  out_args,
amxc_var_t *  ret 
)

Finishes a deferred method and removes the deferred function context.

When the result is available, a callee can finish the deferred method by calling this function. It must provide the final status and the return value.

This will trigger the callback function registered by the caller. The callback function will be called immediately.

Parameters
call_idThe id of the deferred function.
statusThe final status of the RPC method
out_argsOut arguments if any (can be NULL)
retThe return value of the RPC method
Returns
amxd_status_ok if the reply was sent or another status when an error has occured.

Definition at line 249 of file amxd_function_deferred.c.

252  {
253  return amxd_function_deferred_done_impl(call_id, status, out_args, ret, true);
254 }
static amxd_status_t amxd_function_deferred_done_impl(uint64_t call_id, amxd_status_t status, amxc_var_t *out_args, amxc_var_t *ret, bool now)

◆ amxd_function_deferred_done()

amxd_status_t amxd_function_deferred_done ( uint64_t  call_id,
amxd_status_t  status,
amxc_var_t *  out_args,
amxc_var_t *  ret 
)

Finishes a deferred method and removes the deferred function context.

When the result is available, a callee can finish the deferred method by calling this function. It must provide the final status and the return value.

This will trigger the callback function registered by the caller. The callback function will be called from the eventloop, in other words the callback function is scheduled to be called and is not called immediately.

Parameters
call_idThe id of the deferred function.
statusThe final status of the RPC method
out_argsOut arguments if any (can be NULL)
retThe return value of the RPC method
Returns
amxd_status_ok if the reply was send or another status when an error has occured.

Definition at line 242 of file amxd_function_deferred.c.

245  {
246  return amxd_function_deferred_done_impl(call_id, status, out_args, ret, false);
247 }

◆ amxd_function_deferred_get_priv()

void* amxd_function_deferred_get_priv ( uint64_t  call_id)

Gets the callee private data of an deferred function.

When a callee creates a deferred function contexts it can provide private data. Using this method it can retrieve the private data using the deferred call id.

Parameters
call_idThe id of the deferred function.
Returns
The private data that was set with amxd_function_defer

Definition at line 173 of file amxd_function_deferred.c.

173  {
174  void* data = NULL;
176 
177  when_null(call, exit);
178  data = call->called_priv;
179 
180 exit:
181  return data;
182 }
amxd_deferred_ctx_t * amxd_find_deferred(uint64_t call_id)

◆ amxd_function_deferred_remove()

void amxd_function_deferred_remove ( uint64_t  call_id)

Removes a deferred RPC context.

A deferred function context can be removed by the caller or the callee.

When the caller wants to remove a deferred function its deferred callback must be removed first.

If the callee wants to remove a deferred function its cancel callback must be removed first.

Parameters
call_idThe id of the deferred function.

Definition at line 154 of file amxd_function_deferred.c.

154  {
156  amxc_var_t sig_data;
157 
158  amxc_var_init(&sig_data);
159  when_null(call, exit);
160 
161  amxc_var_set_type(&sig_data, AMXC_VAR_ID_HTABLE);
162  amxc_var_add_new_key(&sig_data, "retval");
163  amxc_var_add_key(uint32_t, &sig_data, "status", amxd_status_unknown_error);
164 
165  amxd_cancel_deferred(call, &sig_data);
166  amxd_delete_deferred(&call->it);
167 
168 exit:
169  amxc_var_clean(&sig_data);
170  return;
171 }
static void amxd_delete_deferred(amxc_llist_it_t *it)
static void amxd_cancel_deferred(amxd_deferred_ctx_t *call, amxc_var_t *sig_data)

◆ amxd_function_del_arg()

void amxd_function_del_arg ( amxd_function_t func,
const char *  name 
)

Removes an argument definition from a RPC method definition.

Parameters
funcpointer to a function definition
namethe argument name

Definition at line 168 of file amxd_function_args.c.

168  {
169  amxd_func_arg_t* arg = NULL;
170  when_null(func, exit);
171  when_str_empty(name, exit);
172 
173  arg = amxd_function_get_arg(func, name);
174  when_null(arg, exit);
175 
177  free(arg);
178 
179 exit:
180  return;
181 }
void PRIVATE amxd_function_arg_clean(amxd_func_arg_t *const arg)

◆ amxd_function_delete()

void amxd_function_delete ( amxd_function_t **  func)

Data model RPC method destructor function.

Frees all memory allocated to store the RPC method definition.

If the RPC method was added to a data model object using amxd_object_add_function, the RPC method is removed from that object.

Warning
Removing a RPC method from an object will affect all derived objects as well.
Parameters
funcpointer to a pointer to the RPC method definition

Definition at line 169 of file amxd_function.c.

169  {
170  when_null(func, exit);
171  when_null((*func), exit);
172 
173  amxd_function_clean((*func));
174  free(*func);
175  *func = NULL;
176 
177 exit:
178  return;
179 }

◆ amxd_function_describe()

amxd_status_t amxd_function_describe ( amxd_function_t *const  func,
amxc_var_t *const  value 
)

Fetches the full RPC method definition in a variant.

It can be very handy to get the full definition of the RPC method.

This function is mainly intended for introspection.

Parameters
funcpointer to a function definition
valuevariant where the RPC method defintion can be stored
Returns
amxd_status_ok when the function implementation is set, or another status when an error has occurred.

Definition at line 413 of file amxd_function.c.

414  {
416  amxc_var_t* table = NULL;
417  uint32_t retvalt = 0;
418 
419  static const char* attr_name[] = {
420  "template",
421  "instance",
422  "private",
423  "protected",
424  "asynchronous",
425  };
426 
427  when_null(func, exit);
428  when_null(value, exit);
429 
430  retvalt = amxd_function_get_type(func);
431  amxc_var_set_type(value, AMXC_VAR_ID_HTABLE);
432  amxc_var_add_key(cstring_t, value, "name", amxd_function_get_name(func));
433  amxc_var_add_key(uint32_t, value, "type_id", retvalt);
434  amxc_var_add_key(cstring_t,
435  value,
436  "type_name",
437  amxc_var_get_type_name_from_id(retvalt));
438  table = amxc_var_add_key(amxc_htable_t, value, "attributes", NULL);
439  for(int i = 0; i <= (int) amxd_fattr_max; i++) {
440  amxc_var_add_key(bool,
441  table,
442  attr_name[i],
444  }
445 
446  table = amxc_var_add_key(amxc_llist_t, value, "arguments", NULL);
447  amxc_llist_for_each(it, (&func->args)) {
448  amxd_func_arg_t* farg = amxc_llist_it_get_data(it, amxd_func_arg_t, it);
449  amxc_var_t* arg = amxc_var_add(amxc_htable_t, table, NULL);
450  amxd_function_arg_describe(farg, arg);
451  }
452 
453  table = amxc_var_add_key(amxc_llist_t, value, "flags", NULL);
454  if(func->flags != NULL) {
455  amxc_var_for_each(flag, func->flags) {
456  if(amxc_var_dyncast(bool, flag)) {
457  amxc_var_add(cstring_t, table, amxc_var_key(flag));
458  }
459  }
460  }
461 
463 
464 exit:
465  return status;
466 }
enum _amxd_fattr_id amxd_fattr_id_t
The method attributes.
@ amxd_fattr_max
Definition: amxd_types.h:322
const char * amxd_function_get_name(const amxd_function_t *const func)
Get the name of a method.
amxd_status_t amxd_function_arg_describe(amxd_func_arg_t *const arg, amxc_var_t *const value)
Fetches the argument definition in a variant.
static uint32_t amxd_function_get_type(const amxd_function_t *const func)
Gets the return type of a method.
bool amxd_function_is_attr_set(const amxd_function_t *const func, const amxd_fattr_id_t attr)
Checks if a method attribute is set.
amxc_var_t * flags
Definition: amxd_types.h:348

◆ amxd_function_get_arg()

amxd_func_arg_t* amxd_function_get_arg ( const amxd_function_t *const  func,
const char *  name 
)

Gets the argument definition of a RPC method.

Parameters
funcpointer to a function definition
namethe argument name
Returns
amxd_status_ok when the argument is removed from the RPC method, or another status when an error has occurred.

Definition at line 468 of file amxd_function.c.

469  {
470  amxd_func_arg_t* arg = NULL;
471  when_null(func, exit);
472  when_str_empty(name, exit);
473 
474  amxc_llist_for_each(it, (&func->args)) {
475  arg = amxc_llist_it_get_data(it, amxd_func_arg_t, it);
476  if(strcmp(arg->name, name) == 0) {
477  break;
478  }
479  arg = NULL;
480  }
481 
482 exit:
483  return arg;
484 }

◆ amxd_function_get_attrs()

uint32_t amxd_function_get_attrs ( const amxd_function_t *const  func)

Gets the set attributes of a RPC method.

This function returns the set attributes of a method as a bitmask. To verify if a certain attribute is set, use the macro IS_BIT_SET.

uint32_t attrs = amxd_function_get_attrs(func);
// do something
}
#define IS_BIT_SET(b, f)
Definition: amxd_common.h:66
@ amxd_fattr_instance
Definition: amxd_types.h:312
uint32_t amxd_function_get_attrs(const amxd_function_t *const func)
Gets the set attributes of a RPC method.

To verify that one single attribute is set the function amxd_function_is_attr_set can be used.

Parameters
funcpointer to a function definition
Returns
Returns the attributes set on the method as a bitmask.

Definition at line 339 of file amxd_function.c.

339  {
340  uint32_t attributes = 0;
341  when_null(func, exit);
342 
343  attributes |= func->attr.templ << amxd_fattr_template;
344  attributes |= func->attr.instance << amxd_fattr_instance;
345  attributes |= func->attr.priv << amxd_fattr_private;
346  attributes |= func->attr.prot << amxd_fattr_protected;
347  attributes |= func->attr.async << amxd_fattr_async;
348 
349 exit:
350  return attributes;
351 }
@ amxd_fattr_template
Definition: amxd_types.h:311
@ amxd_fattr_async
Definition: amxd_types.h:321
@ amxd_fattr_private
Definition: amxd_types.h:313
@ amxd_fattr_protected
Definition: amxd_types.h:317
uint32_t templ
Definition: amxd_types.h:326
uint32_t priv
Definition: amxd_types.h:329
uint32_t async
Definition: amxd_types.h:331
uint32_t prot
Definition: amxd_types.h:330
uint32_t instance
Definition: amxd_types.h:327

◆ amxd_function_get_base()

amxd_function_t* amxd_function_get_base ( const amxd_function_t *const  func)

Get the base function definition of an overridden function.

In derived objects it is possible to override methods and set a different implementation. Using this function the base definition from which the method is derived is returned.

Parameters
funcpointer to a function definition
Returns
The function definition pointer of the base definition, if there is no base definition, the given definition pointer is returned.

Definition at line 237 of file amxd_function.c.

237  {
238  amxd_function_t* base = NULL;
239  amxd_object_t* object = amxd_function_get_owner(func);
240 
241  when_null(object, exit);
242 
245  func->name);
246  } else {
247  if(amxc_llist_it_is_in_list(&object->derived_from)) {
248  amxd_object_t* super = NULL;
249  super = amxc_container_of(object->derived_from.llist,
251  derived_objects);
252  base = amxd_object_get_function(super, func->name);
253  }
254  }
255 
256 exit:
257  return base;
258 }
@ amxd_object_instance
Definition: amxd_types.h:186
amxd_object_t * amxd_object_get_parent(const amxd_object_t *const object)
Get the parent object.
amxd_function_t * amxd_object_get_function(const amxd_object_t *const object, const char *name)
Get the definition of a RPC method from an object.
static amxd_object_type_t amxd_object_get_type(const amxd_object_t *const object)
Returns the object type.
Definition: amxd_object.h:586
amxd_object_t * amxd_function_get_owner(const amxd_function_t *const func)
Get the object pointer of the object containing the function definition.
amxc_llist_it_t derived_from
Definition: amxd_types.h:249

◆ amxd_function_get_name()

const char* amxd_function_get_name ( const amxd_function_t *const  func)

Get the name of a method.

Returns the name of the method. There is no need to free the returned pointer.

Parameters
funcpointer to a function definition
Returns
The name of the method.

Definition at line 279 of file amxd_function.c.

279  {
280  return func == NULL ? NULL : func->name;
281 }

◆ amxd_function_get_owner()

amxd_object_t* amxd_function_get_owner ( const amxd_function_t *const  func)

Get the object pointer of the object containing the function definition.

When using a derived object, the object containing the function defintion can be different than the object where the function definition pointer was retrieved from.

It is possible to change the implementation of the method in a derived object. This can be done using amxd_object_change_function. When changing the implementation in a derived object, a copy of the function definition is created and stored in the derived object. To retrieve the base implementation use amxd_function_get_base.

Parameters
funcpointer to a function definition
Returns
The object pointer containing the method definition, or NULL if the object definition is not owned by an object.

Definition at line 226 of file amxd_function.c.

226  {
227  amxd_object_t* object = NULL;
228  when_null(func, exit);
229  when_null(func->it.llist, exit);
230 
231  object = amxc_container_of(func->it.llist, amxd_object_t, functions);
232 
233 exit:
234  return object;
235 }
amxc_llist_it_t it
Definition: amxd_types.h:342

◆ amxd_function_get_type()

static uint32_t amxd_function_get_type ( const amxd_function_t *const  func)
inlinestatic

Gets the return type of a method.

Returns the return type of a method. The return type matches with a amxc variant type.

Parameters
funcpointer to a function definition
Returns
The return type of the method.

Definition at line 260 of file amxd_function.h.

260  {
261  return func == NULL ? AMXC_VAR_ID_NULL : func->ret_type;
262 }

◆ amxd_function_has_flag()

bool amxd_function_has_flag ( const amxd_function_t *const  func,
const char *  flag 
)

Checks if a flag is set.

A flag is any arbitrary string and can be set or unset.

The flags set on a function can be seen in the description data of the function.

When a derived object overrides a function, the flags are reset for that derived object.

Parameters
funcpointer to a function definition
flagthe flag name
Returns
true when the flag is set

Definition at line 389 of file amxd_function.c.

389  {
390  bool retval = false;
391  when_null(func, exit);
392  when_null(flag, exit);
393  when_true(*flag == 0, exit);
394 
395  retval = amxd_common_has_flag(func->flags, flag);
396 
397 exit:
398  return retval;
399 }
bool PRIVATE amxd_common_has_flag(const amxc_var_t *const flags, const char *flag)
Definition: amxd_dm_priv.c:652

◆ amxd_function_is_attr_set()

bool amxd_function_is_attr_set ( const amxd_function_t *const  func,
const amxd_fattr_id_t  attr 
)

Checks if a method attribute is set.

The following attribute identifiers can be checked

Parameters
funcpointer to a function definition
attrthe method attribute id
Returns
Returns true if attribute is set and false when unset

Definition at line 353 of file amxd_function.c.

354  {
355  uint32_t flags = 0;
356  bool retval = false;
357  when_null(func, exit);
358  when_true(attr < 0 || attr > amxd_fattr_max, exit);
359 
360  flags = amxd_function_get_attributes(func);
361  retval = (flags & (1 << attr)) != 0 ? true : false;
362 
363 exit:
364  return retval;
365 }
static uint32_t amxd_function_get_attributes(const amxd_function_t *const func)

◆ amxd_function_new()

amxd_status_t amxd_function_new ( amxd_function_t **  func,
const char *  name,
const uint32_t  ret_type,
amxd_object_fn_t  impl 
)

Data model RPC method constructor function.

Allocates memory for a new data model rpc method and initializes the struct _amxd_function.

Creates a RPC method definition. Each RPC method has a return type and must be one of the available amxc variant types. A name must be provided as well.

When adding the rpc method to an object using amxd_object_add_function the name of the RPC method should not exist in that object as a RPC method.

Optionally a function pointer can be provided. If no function implementation is set, the function definition exists, but calling the function will fail.

Function implementation must match with this prototype definition:

amxc_var_t* args,
amxc_var_t* ret);
amxd_status_t(* amxd_object_fn_t)(amxd_object_t *object, amxd_function_t *func, amxc_var_t *args, amxc_var_t *ret)
Definition: amxd_types.h:272

To be able to call the function it must be added to an object.

When the RPC method definition is not added to any data model object, the pointer must be freed using amxd_function_delete.

When the RPC method definition is added to a data model object, it will be automatically freed when the object that contains the method is deleted.

Parameters
funcpointer to a pointer to the new RPC method definition
namethe name of the RPC method
ret_typethe return type of the RPC method, must be a valid amxc variant type
implpointer to the implementation function
Returns
amxd_status_ok when the function definition is created, or another status when an error has occurred.

Definition at line 146 of file amxd_function.c.

149  {
151  when_null(func, exit);
152  when_true_status(!amxd_name_is_valid(name),
153  exit,
154  retval = amxd_status_invalid_name);
155 
156  *func = (amxd_function_t*) calloc(1, sizeof(amxd_function_t));
157  when_null((*func), exit);
158 
159  retval = amxd_function_init(*func, name, ret_type, impl);
160 
161 exit:
162  if((retval != 0) && (func != NULL)) {
163  free(*func);
164  *func = NULL;
165  }
166  return retval;
167 }
bool amxd_name_is_valid(const char *name)
Definition: amxd_common.c:115
@ amxd_status_invalid_name
Definition: amxd_types.h:86

◆ amxd_function_new_arg()

amxd_status_t amxd_function_new_arg ( amxd_function_t func,
const char *  name,
const uint32_t  type,
amxc_var_t *  default_value 
)

Adds an argument definition to a RPC method definition.

Parameters
funcpointer to a function definition
namethe argument name
typethe argument type, must be one of the amxc variant types
default_valuea default value for the argument
Returns
amxd_status_ok when the argument is added to the RPC method, or another status when an error has occurred.

Definition at line 140 of file amxd_function_args.c.

143  {
145  amxd_func_arg_t* arg = NULL;
146  when_null(func, exit);
147 
148  when_str_empty_status(name, exit, retval = amxd_status_invalid_name);
149  when_true_status(!amxd_function_arg_valid_name(func, name),
150  exit,
151  retval = amxd_status_invalid_name);
152 
153  arg = (amxd_func_arg_t*) calloc(1, sizeof(amxd_func_arg_t));
154  when_null(arg, exit);
155 
156  retval = amxd_function_arg_init(arg, name, type, default_value);
157 
158  if(retval == amxd_status_ok) {
159  amxc_llist_append(&func->args, &arg->it);
160  }
161 exit:
162  if(retval != amxd_status_ok) {
163  free(arg);
164  }
165  return retval;
166 }
static bool amxd_function_arg_valid_name(amxd_function_t *func, const char *name)
static amxd_status_t amxd_function_arg_init(amxd_func_arg_t *const arg, const char *name, uint32_t type, amxc_var_t *default_value)
amxc_llist_it_t it
Definition: amxd_types.h:298

◆ amxd_function_set_attr()

amxd_status_t amxd_function_set_attr ( amxd_function_t func,
const amxd_fattr_id_t  attr,
const bool  enable 
)

Sets or unsets a method attribute.

The following attributes can be set - unset:

Note
The attributes amxd_fattr_template and amxd_fattr_instance are ignored when the method is added to a singleton object.
Parameters
funcpointer to a function definition
attrthe attribute id
enablewhen true, sets the attribute, when false unsets the attribute
Returns
Returns amxd_status_ok when attribute is changed, any other when failed

Definition at line 283 of file amxd_function.c.

285  {
287  uint32_t flags = 0;
288  when_null(func, exit);
289 
290  when_true_status(attr < 0 || attr > amxd_fattr_max,
291  exit,
292  retval = amxd_status_invalid_attr);
293 
294  flags = amxd_function_get_attributes(func);
295 
296  if(enable) {
297  flags |= (1 << attr);
298  } else {
299  flags &= ~(1 << attr);
300  }
301 
302  amxd_function_set_attributes(func, flags);
303 
304  retval = amxd_status_ok;
305 
306 exit:
307  return retval;
308 }
static void amxd_function_set_attributes(amxd_function_t *const func, const uint32_t attr)

◆ amxd_function_set_attrs()

amxd_status_t amxd_function_set_attrs ( amxd_function_t func,
const uint32_t  bitmask,
bool  enable 
)

Sets or unsets method attributes using a bitmap.

The following attributes can be set - unset:

Use the macro SET_BIT to transform the attribute id to a bit. The bits can be joined together using the bitwise or operator '|'

true);
amxd_status_t amxd_function_set_attrs(amxd_function_t *func, const uint32_t bitmask, bool enable)
Sets or unsets method attributes using a bitmap.

When setting or unsetting one single attribute the function amxd_function_set_attr can be used.

Note
The attributes amxd_fattr_template and amxd_fattr_instance are ignored when the method is added to a singleton object.
Parameters
funcpointer to a function definition
bitmaskthe function attribute bitmask
enablewhen true, sets the attributes, when false unsets the attributes
Returns
Returns amxd_status_ok when attributes are changed, any other status when failed

Definition at line 310 of file amxd_function.c.

312  {
314  uint32_t flags = 0;
315  uint32_t all = 0;
316 
317  for(int i = 0; i <= amxd_fattr_max; i++) {
318  all |= SET_BIT(i);
319  }
320 
321  when_null(func, exit);
322  when_true_status(bitmask > all, exit, retval = amxd_status_invalid_attr);
323 
324  flags = amxd_function_get_attributes(func);
325 
326  if(enable) {
327  flags |= bitmask;
328  } else {
329  flags &= ~bitmask;
330  }
331 
332  amxd_function_set_attributes(func, flags);
333  retval = amxd_status_ok;
334 
335 exit:
336  return retval;
337 }

◆ amxd_function_set_deferred_cb()

amxd_status_t amxd_function_set_deferred_cb ( uint64_t  call_id,
amxp_deferred_fn_t  cb,
void *  priv 
)

Sets a callback function to get the result of the deferred call.

When a caller invokes an object method with amxd_object_invoke_function and gets amxd_status_defer as status code, the caller can set a callback function that will be called when the deferred methods finishes.

The call identifier will be provided in the return value.

Parameters
call_idThe id of the deferred function.
cbThe callback function
privSome private data, will be passed to the callback function
Returns
amxd_status_ok when the callback function is set or another status when an error has occurred.

Definition at line 184 of file amxd_function_deferred.c.

186  {
189 
190  when_null(call, exit);
191 
192  call->cb = cb;
193  call->caller_priv = priv;
194 
195  rv = amxd_status_ok;
196 
197 exit:
198  return rv;
199 }
@ amxd_status_invalid_function
Definition: amxd_types.h:84
amxp_deferred_fn_t cb
Definition: amxd_dm_priv.h:65

◆ amxd_function_set_flag()

void amxd_function_set_flag ( amxd_function_t func,
const char *  flag 
)

Sets a flag on a function.

A flag is any arbitrary string and can be set or unset.

The flags set on a function can be seen in the description data of the function.

When a derived object overrides a function, the flags are reset for that derived object.

Parameters
funcpointer to a function definition
flagthe flag name

Definition at line 367 of file amxd_function.c.

367  {
368  when_null(func, exit);
369  when_null(flag, exit);
370  when_true(*flag == 0, exit);
371 
372  amxd_common_set_flag(&func->flags, flag);
373 
374 exit:
375  return;
376 }
void PRIVATE amxd_common_set_flag(amxc_var_t **flags, const char *flag)
Definition: amxd_dm_priv.c:617

◆ amxd_function_set_impl()

amxd_status_t amxd_function_set_impl ( amxd_function_t *const  func,
amxd_object_fn_t  impl 
)

Set an implementation for a RPC method.

Data model object can contain methods. Remote clients can invoke these methods. An implementation must be set, the implementation must match with this prototype:

amxc_var_t* args,
amxc_var_t* ret);
Note
When changing the method implementation with this function, and the method is added to an object that has derived objects the implementation is changed for all these object. To change the implementation for one single derived object use amxd_object_change_function.
Parameters
funcpointer to a function definition
implfunction pointer to the implementation
Returns
Returns amxd_status_ok when implementation is set, any other status code when failed.

Definition at line 401 of file amxd_function.c.

402  {
404  when_null(func, exit);
405 
406  func->impl = impl;
407  retval = amxd_status_ok;
408 
409 exit:
410  return retval;
411 }

◆ amxd_function_unset_flag()

void amxd_function_unset_flag ( amxd_function_t func,
const char *  flag 
)

Removes a flag from a function.

A flag is any arbitrary string and can be set or unset.

The flags set on a function can be seen in the description data of the function.

When a derived object overrides a function, the flags are reset for that derived object.

Parameters
funcpointer to a function definition
flagthe flag name

Definition at line 378 of file amxd_function.c.

378  {
379  when_null(func, exit);
380  when_null(flag, exit);
381  when_true(*flag == 0, exit);
382 
383  amxd_common_unset_flag(&func->flags, flag);
384 
385 exit:
386  return;
387 }
void PRIVATE amxd_common_unset_flag(amxc_var_t **flags, const char *flag)
Definition: amxd_dm_priv.c:634