Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
res_stasis_device_state.c File Reference
#include "asterisk.h"
#include "asterisk/astdb.h"
#include "asterisk/astobj2.h"
#include "asterisk/module.h"
#include "asterisk/stasis_app_impl.h"
#include "asterisk/stasis_app_device_state.h"
Include dependency graph for res_stasis_device_state.c:

Go to the source code of this file.

Data Structures

struct  device_state_subscription
 Device state subscription object. More...
 

Macros

#define DEVICE_STATE_ALL   "__AST_DEVICE_STATE_ALL_TOPIC"
 
#define DEVICE_STATE_BUCKETS   37
 
#define DEVICE_STATE_FAMILY   "StasisDeviceState"
 
#define DEVICE_STATE_PROVIDER_STASIS   "Stasis"
 
#define DEVICE_STATE_SCHEME_STASIS   "Stasis:"
 
#define DEVICE_STATE_SCHEME_SUB   "deviceState:"
 
#define DEVICE_STATE_SIZE   64
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static void device_state_cb (void *data, struct stasis_subscription *sub, struct stasis_message *msg)
 
static struct device_state_subscriptiondevice_state_subscription_create (const struct stasis_app *app, const char *device_name)
 
static void device_state_subscription_destroy (void *obj)
 
static int device_state_subscriptions_cmp (void *obj, void *arg, int flags)
 
static int device_state_subscriptions_hash (const void *obj, const int flags)
 
static int device_to_json_cb (void *obj, void *arg, void *data, int flags)
 
static void devices_to_json (const struct stasis_app *app, struct ast_json *json)
 
static void * find_device_state (const struct stasis_app *app, const char *name)
 
static struct device_state_subscriptionfind_device_state_subscription (struct stasis_app *app, const char *name)
 
static int is_subscribed_device_state (struct stasis_app *app, const char *name)
 
static int is_subscribed_device_state_lock (struct stasis_app *app, const char *name)
 
static int load_module (void)
 
static void populate_cache (void)
 
static void remove_device_state_subscription (struct device_state_subscription *sub)
 
static void send_device_state (struct device_state_subscription *sub, const char *name, enum ast_device_state state)
 
enum stasis_device_state_result stasis_app_device_state_delete (const char *name)
 Delete a device controlled by ARI. More...
 
struct ast_jsonstasis_app_device_state_to_json (const char *name, enum ast_device_state state)
 Convert device state to json. More...
 
enum stasis_device_state_result stasis_app_device_state_update (const char *name, const char *value)
 Changes the state of a device controlled by ARI. More...
 
struct ast_jsonstasis_app_device_states_to_json (void)
 Convert device states to json array. More...
 
static enum ast_device_state stasis_device_state_cb (const char *data)
 
static int subscribe_device_state (struct stasis_app *app, void *obj)
 
static int unload_module (void)
 
static int unsubscribe_device_state (struct stasis_app *app, const char *name)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "Stasis application device state support" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .requires = "res_stasis", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
struct stasis_app_event_source device_state_event_source
 
static struct ao2_containerdevice_state_subscriptions
 

Macro Definition Documentation

◆ DEVICE_STATE_ALL

#define DEVICE_STATE_ALL   "__AST_DEVICE_STATE_ALL_TOPIC"

The key used for tracking a subscription to all device states

Definition at line 46 of file res_stasis_device_state.c.

Referenced by device_state_subscription_create(), is_subscribed_device_state(), and subscribe_device_state().

◆ DEVICE_STATE_BUCKETS

#define DEVICE_STATE_BUCKETS   37

Number of hash buckets for device state subscriptions

Definition at line 43 of file res_stasis_device_state.c.

Referenced by load_module().

◆ DEVICE_STATE_FAMILY

#define DEVICE_STATE_FAMILY   "StasisDeviceState"

◆ DEVICE_STATE_PROVIDER_STASIS

#define DEVICE_STATE_PROVIDER_STASIS   "Stasis"

Stasis device state provider

Definition at line 36 of file res_stasis_device_state.c.

Referenced by load_module(), and unload_module().

◆ DEVICE_STATE_SCHEME_STASIS

#define DEVICE_STATE_SCHEME_STASIS   "Stasis:"

◆ DEVICE_STATE_SCHEME_SUB

#define DEVICE_STATE_SCHEME_SUB   "deviceState:"

Scheme for device state subscriptions

Definition at line 40 of file res_stasis_device_state.c.

◆ DEVICE_STATE_SIZE

#define DEVICE_STATE_SIZE   64

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 490 of file res_stasis_device_state.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 490 of file res_stasis_device_state.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 490 of file res_stasis_device_state.c.

◆ device_state_cb()

static void device_state_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message msg 
)
static

Definition at line 301 of file res_stasis_device_state.c.

References ao2_ref, ast_device_state_message_type(), ast_device_state_message::device, ast_device_state_message::eid, send_device_state(), stasis_message_data(), stasis_message_type(), stasis_subscription_final_message(), and ast_device_state_message::state.

Referenced by subscribe_device_state().

303 {
304  struct ast_device_state_message *device_state;
305 
306  if (stasis_subscription_final_message(sub, msg)) {
307  /* Remove stasis subscription's reference to device_state_subscription */
308  ao2_ref(data, -1);
309  return;
310  }
311 
313  return;
314  }
315 
316  device_state = stasis_message_data(msg);
317  if (device_state->eid) {
318  /* ignore non-aggregate states */
319  return;
320  }
321 
322  send_device_state(data, device_state->device, device_state->state);
323 }
enum ast_device_state state
Definition: devicestate.h:250
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
static void send_device_state(struct device_state_subscription *sub, const char *name, enum ast_device_state state)
struct stasis_message_type * ast_device_state_message_type(void)
Get the Stasis message type for device state messages.
const struct ast_eid * eid
The EID of the server where this message originated.
Definition: devicestate.h:248
#define ao2_ref(o, delta)
Definition: astobj2.h:464
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
int stasis_subscription_final_message(struct stasis_subscription *sub, struct stasis_message *msg)
Determine whether a message is the final message to be received on a subscription.
Definition: stasis.c:1176
The structure that contains device state.
Definition: devicestate.h:240

◆ device_state_subscription_create()

static struct device_state_subscription* device_state_subscription_create ( const struct stasis_app app,
const char *  device_name 
)
static

Definition at line 112 of file res_stasis_device_state.c.

References ao2_alloc, ao2_ref, device_state_subscription::app_name, ast_string_field_init, ast_string_field_set, ast_strlen_zero, DEVICE_STATE_ALL, device_state_subscription_destroy(), NULL, stasis_app_name(), and device_state_subscription::sub.

Referenced by find_device_state(), and subscribe_device_state().

114 {
116  const char *app_name = stasis_app_name(app);
117  size_t size;
118 
121  }
122 
123  size = strlen(device_name) + strlen(app_name) + 2;
124 
125  sub = ao2_alloc(sizeof(*sub), device_state_subscription_destroy);
126  if (!sub) {
127  return NULL;
128  }
129 
130  if (ast_string_field_init(sub, size)) {
131  ao2_ref(sub, -1);
132  return NULL;
133  }
134 
135  ast_string_field_set(sub, app_name, app_name);
137  return sub;
138 }
Device state subscription object.
const ast_string_field device_name
#define DEVICE_STATE_ALL
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
const char * stasis_app_name(const struct stasis_app *app)
Retrieve an application's name.
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const char * app_name(struct ast_app *app)
Definition: pbx_app.c:463
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
struct stasis_forward * sub
Definition: res_corosync.c:240
static void device_state_subscription_destroy(void *obj)
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ device_state_subscription_destroy()

static void device_state_subscription_destroy ( void *  obj)
static

Definition at line 106 of file res_stasis_device_state.c.

References ast_string_field_free_memory, and device_state_subscription::sub.

Referenced by device_state_subscription_create().

107 {
108  struct device_state_subscription *sub = obj;
110 }
Device state subscription object.
struct stasis_forward * sub
Definition: res_corosync.c:240
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368

◆ device_state_subscriptions_cmp()

static int device_state_subscriptions_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 79 of file res_stasis_device_state.c.

References device_state_subscription::app_name, ast_assert, CMP_MATCH, CMP_STOP, device_state_subscription::device_name, OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, OBJ_SEARCH_OBJECT, and OBJ_SEARCH_PARTIAL_KEY.

Referenced by load_module().

80 {
81  const struct device_state_subscription *object_left = obj;
82  const struct device_state_subscription *object_right = arg;
83  int cmp;
84 
85  switch (flags & OBJ_SEARCH_MASK) {
86  case OBJ_SEARCH_OBJECT:
87  /* find objects matching both device and app names */
88  if (strcmp(object_left->device_name,
89  object_right->device_name)) {
90  return 0;
91  }
92  cmp = strcmp(object_left->app_name, object_right->app_name);
93  break;
94  case OBJ_SEARCH_KEY:
96  ast_assert(0); /* not supported by container */
97  /* fall through */
98  default:
99  cmp = 0;
100  break;
101  }
102 
103  return cmp ? 0 : CMP_MATCH | CMP_STOP;
104 }
const ast_string_field app_name
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
Device state subscription object.
const ast_string_field device_name
#define ast_assert(a)
Definition: utils.h:695
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition: astobj2.h:1120
The arg parameter is an object of the same type.
Definition: astobj2.h:1091
Search option field mask.
Definition: astobj2.h:1076

◆ device_state_subscriptions_hash()

static int device_state_subscriptions_hash ( const void *  obj,
const int  flags 
)
static

Definition at line 63 of file res_stasis_device_state.c.

References ast_assert, ast_str_hash(), device_state_subscription::device_name, OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, and OBJ_SEARCH_OBJECT.

Referenced by load_module().

64 {
65  const struct device_state_subscription *object;
66 
67  switch (flags & OBJ_SEARCH_MASK) {
68  case OBJ_SEARCH_OBJECT:
69  object = obj;
70  return ast_str_hash(object->device_name);
71  case OBJ_SEARCH_KEY:
72  default:
73  /* Hash can only work on something with a full key. */
74  ast_assert(0);
75  return 0;
76  }
77 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
Device state subscription object.
const ast_string_field device_name
#define ast_assert(a)
Definition: utils.h:695
The arg parameter is an object of the same type.
Definition: astobj2.h:1091
Search option field mask.
Definition: astobj2.h:1076
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1206

◆ device_to_json_cb()

static int device_to_json_cb ( void *  obj,
void *  arg,
void *  data,
int  flags 
)
static

Definition at line 423 of file res_stasis_device_state.c.

References device_state_subscription::app_name, array(), ast_json_array_append(), ast_json_string_create(), device_state_subscription::device_name, and device_state_subscription::sub.

Referenced by devices_to_json().

424 {
425  struct device_state_subscription *sub = obj;
426  const char *app_name = arg;
427  struct ast_json *array = data;
428 
429  if (strcmp(sub->app_name, app_name)) {
430  return 0;
431  }
432 
434  array, ast_json_string_create(sub->device_name));
435  return 0;
436 
437 }
const ast_string_field app_name
Device state subscription object.
const ast_string_field device_name
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
Definition: json.c:268
int ast_json_array_append(struct ast_json *array, struct ast_json *value)
Append to an array.
Definition: json.c:368
static int array(struct ast_channel *chan, const char *cmd, char *var, const char *value)
const char * app_name(struct ast_app *app)
Definition: pbx_app.c:463
struct stasis_forward * sub
Definition: res_corosync.c:240
Abstract JSON element (object, array, string, int, ...).

◆ devices_to_json()

static void devices_to_json ( const struct stasis_app app,
struct ast_json json 
)
static

Definition at line 439 of file res_stasis_device_state.c.

References ao2_callback_data, array(), ast_json_array_create(), ast_json_object_set(), device_to_json_cb(), OBJ_NODATA, and stasis_app_name().

440 {
443  device_to_json_cb, (void *)stasis_app_name(app), array);
444  ast_json_object_set(json, "device_names", array);
445 }
static struct ao2_container * device_state_subscriptions
int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
Set a field in a JSON object.
Definition: json.c:404
const char * stasis_app_name(const struct stasis_app *app)
Retrieve an application's name.
struct ast_json * ast_json_array_create(void)
Create a empty JSON array.
Definition: json.c:352
static int array(struct ast_channel *chan, const char *cmd, char *var, const char *value)
#define ao2_callback_data(container, flags, cb_fn, arg, data)
Definition: astobj2.h:1743
Abstract JSON element (object, array, string, int, ...).
static int device_to_json_cb(void *obj, void *arg, void *data, int flags)

◆ find_device_state()

static void* find_device_state ( const struct stasis_app app,
const char *  name 
)
static

Definition at line 325 of file res_stasis_device_state.c.

References device_state_subscription_create().

326 {
328 }
static struct device_state_subscription * device_state_subscription_create(const struct stasis_app *app, const char *device_name)
static const char name[]
Definition: cdr_mysql.c:74

◆ find_device_state_subscription()

static struct device_state_subscription* find_device_state_subscription ( struct stasis_app app,
const char *  name 
)
static

Definition at line 140 of file res_stasis_device_state.c.

References ao2_find, device_state_subscription::app_name, OBJ_NOLOCK, OBJ_SEARCH_OBJECT, and stasis_app_name().

Referenced by is_subscribed_device_state(), and unsubscribe_device_state().

142 {
143  struct device_state_subscription dummy_sub = {
144  .app_name = stasis_app_name(app),
145  .device_name = name
146  };
147 
149 }
static struct ao2_container * device_state_subscriptions
const ast_string_field app_name
Device state subscription object.
Assume that the ao2_container is already locked.
Definition: astobj2.h:1067
const char * stasis_app_name(const struct stasis_app *app)
Retrieve an application's name.
static const char name[]
Definition: cdr_mysql.c:74
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
The arg parameter is an object of the same type.
Definition: astobj2.h:1091

◆ is_subscribed_device_state()

static int is_subscribed_device_state ( struct stasis_app app,
const char *  name 
)
static

Definition at line 330 of file res_stasis_device_state.c.

References ao2_ref, DEVICE_STATE_ALL, find_device_state_subscription(), and device_state_subscription::sub.

Referenced by is_subscribed_device_state_lock(), and subscribe_device_state().

331 {
333 
335  if (sub) {
336  ao2_ref(sub, -1);
337  return 1;
338  }
339 
341  if (sub) {
342  ao2_ref(sub, -1);
343  return 1;
344  }
345 
346  return 0;
347 }
Device state subscription object.
#define DEVICE_STATE_ALL
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct device_state_subscription * find_device_state_subscription(struct stasis_app *app, const char *name)
static const char name[]
Definition: cdr_mysql.c:74
struct stasis_forward * sub
Definition: res_corosync.c:240

◆ is_subscribed_device_state_lock()

static int is_subscribed_device_state_lock ( struct stasis_app app,
const char *  name 
)
static

Definition at line 349 of file res_stasis_device_state.c.

References ao2_lock, ao2_unlock, and is_subscribed_device_state().

350 {
351  int is_subscribed;
352 
354  is_subscribed = is_subscribed_device_state(app, name);
356 
357  return is_subscribed;
358 }
static struct ao2_container * device_state_subscriptions
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ao2_lock(a)
Definition: astobj2.h:718
static int is_subscribed_device_state(struct stasis_app *app, const char *name)
static const char name[]
Definition: cdr_mysql.c:74

◆ load_module()

static int load_module ( void  )
static

Definition at line 456 of file res_stasis_device_state.c.

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ast_devstate_prov_add(), ast_devstate_prov_del(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, DEVICE_STATE_BUCKETS, DEVICE_STATE_PROVIDER_STASIS, device_state_subscriptions_cmp(), device_state_subscriptions_hash(), NULL, populate_cache(), stasis_app_register_event_source(), and stasis_device_state_cb().

Referenced by unload_module().

457 {
458  populate_cache();
462  }
463 
470  }
471 
474 }
static struct ao2_container * device_state_subscriptions
int ast_devstate_prov_del(const char *label)
Remove device state provider.
Definition: devicestate.c:418
int ast_devstate_prov_add(const char *label, ast_devstate_prov_cb_type callback)
Add device state provider.
Definition: devicestate.c:391
static void populate_cache(void)
#define NULL
Definition: resample.c:96
struct stasis_app_event_source device_state_event_source
static enum ast_device_state stasis_device_state_cb(const char *data)
#define DEVICE_STATE_PROVIDER_STASIS
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
static int device_state_subscriptions_hash(const void *obj, const int flags)
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define DEVICE_STATE_BUCKETS
static int device_state_subscriptions_cmp(void *obj, void *arg, int flags)
void stasis_app_register_event_source(struct stasis_app_event_source *obj)
Register an application event source.
Definition: res_stasis.c:1816

◆ populate_cache()

static void populate_cache ( void  )
static

Definition at line 275 of file res_stasis_device_state.c.

References ast_db_freetree(), ast_db_gettree(), AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_devstate_val(), ast_strlen_zero, ast_db_entry::data, DEVICE_STATE_FAMILY, DEVICE_STATE_SCHEME_STASIS, ast_db_entry::key, name, ast_db_entry::next, NULL, and RAII_VAR.

Referenced by load_module().

276 {
277  RAII_VAR(struct ast_db_entry *, tree,
279  struct ast_db_entry *entry;
280 
281  for (entry = tree; entry; entry = entry->next) {
282  const char *name = strrchr(entry->key, '/');
283  if (!ast_strlen_zero(name)) {
285  ast_devstate_val(entry->data),
286  AST_DEVSTATE_CACHABLE, "%s%s\n",
287  DEVICE_STATE_SCHEME_STASIS, name + 1);
288  }
289  }
290 }
#define DEVICE_STATE_SCHEME_STASIS
void ast_db_freetree(struct ast_db_entry *entry)
Free structure created by ast_db_gettree()
Definition: main/db.c:598
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_db_entry * next
Definition: astdb.h:32
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510
enum ast_device_state ast_devstate_val(const char *val)
Convert device state from text to integer value.
Definition: devicestate.c:260
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ast_db_entry * ast_db_gettree(const char *family, const char *keytree)
Get a list of values within the astdb tree.
Definition: main/db.c:531
Definition: astdb.h:31
char data[0]
Definition: astdb.h:34
static const char name[]
Definition: cdr_mysql.c:74
#define DEVICE_STATE_FAMILY
Definition: search.h:40
char * key
Definition: astdb.h:33

◆ remove_device_state_subscription()

static void remove_device_state_subscription ( struct device_state_subscription sub)
static

Definition at line 151 of file res_stasis_device_state.c.

References ao2_unlink_flags, OBJ_NOLOCK, stasis_unsubscribe_and_join(), and device_state_subscription::sub.

Referenced by unsubscribe_device_state().

153 {
154  if (sub->sub) {
155  sub->sub = stasis_unsubscribe_and_join(sub->sub);
156  }
158 }
static struct ao2_container * device_state_subscriptions
Assume that the ao2_container is already locked.
Definition: astobj2.h:1067
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Definition: stasis.c:1136
struct stasis_subscription * sub
#define ao2_unlink_flags(container, obj, flags)
Definition: astobj2.h:1622

◆ send_device_state()

static void send_device_state ( struct device_state_subscription sub,
const char *  name,
enum ast_device_state  state 
)
static

Definition at line 191 of file res_stasis_device_state.c.

References device_state_subscription::app_name, ast_json_pack(), ast_json_timeval(), ast_json_unref(), ast_log, ast_tvnow(), LOG_ERROR, NULL, RAII_VAR, stasis_app_device_state_to_json(), and stasis_app_send().

Referenced by device_state_cb().

193 {
194  RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
195 
196  json = ast_json_pack("{s:s, s:s, s:o, s:o}",
197  "type", "DeviceStateChanged",
198  "application", sub->app_name,
199  "timestamp", ast_json_timeval(ast_tvnow(), NULL),
200  "device_state", stasis_app_device_state_to_json(
201  name, state));
202 
203  if (!json) {
204  ast_log(LOG_ERROR, "Unable to create device state json object\n");
205  return;
206  }
207 
208  stasis_app_send(sub->app_name, json);
209 }
const ast_string_field app_name
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ast_json * ast_json_timeval(const struct timeval tv, const char *zone)
Construct a timeval as JSON.
Definition: json.c:649
#define LOG_ERROR
Definition: logger.h:285
static const char name[]
Definition: cdr_mysql.c:74
int stasis_app_send(const char *app_name, struct ast_json *message)
Send a message to the given Stasis application.
Definition: res_stasis.c:1656
struct ast_json * stasis_app_device_state_to_json(const char *name, enum ast_device_state state)
Convert device state to json.
Abstract JSON element (object, array, string, int, ...).

◆ stasis_app_device_state_delete()

enum stasis_device_state_result stasis_app_device_state_delete ( const char *  name)

Delete a device controlled by ARI.

Parameters
namethe name of the ARI controlled device

stasis device state application result.

Definition at line 244 of file res_stasis_device_state.c.

References ast_db_del(), ast_device_state_clear_cache(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_log, ast_strlen_zero, DEVICE_STATE_FAMILY, DEVICE_STATE_SCHEME_STASIS, LOG_ERROR, name, STASIS_DEVICE_STATE_MISSING, STASIS_DEVICE_STATE_NOT_CONTROLLED, STASIS_DEVICE_STATE_OK, and STASIS_DEVICE_STATE_UNKNOWN.

Referenced by ast_ari_device_states_delete().

245 {
246  const char *full_name = name;
247  size_t size = strlen(DEVICE_STATE_SCHEME_STASIS);
248 
249  if (strncasecmp(name, DEVICE_STATE_SCHEME_STASIS, size)) {
250  ast_log(LOG_ERROR, "Can only delete '%s' device states!\n",
253  }
254 
255  name += size;
256  if (ast_strlen_zero(name)) {
257  ast_log(LOG_ERROR, "Delete requires a device name!\n");
259  }
260 
261  if (ast_device_state_clear_cache(full_name)) {
263  }
264 
266 
267  /* send state change for delete */
271 
272  return STASIS_DEVICE_STATE_OK;
273 }
#define DEVICE_STATE_SCHEME_STASIS
int ast_device_state_clear_cache(const char *device)
Clear the device from the stasis cache.
Definition: devicestate.c:688
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510
#define LOG_ERROR
Definition: logger.h:285
static const char name[]
Definition: cdr_mysql.c:74
#define DEVICE_STATE_FAMILY
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
Definition: main/db.c:429

◆ stasis_app_device_state_to_json()

struct ast_json* stasis_app_device_state_to_json ( const char *  name,
enum ast_device_state  state 
)

Convert device state to json.

Parameters
namethe name of the device
statethe device state
Returns
JSON representation.
NULL on error.

Definition at line 160 of file res_stasis_device_state.c.

References ast_devstate_str(), and ast_json_pack().

Referenced by ast_ari_device_states_get(), send_device_state(), and stasis_app_device_states_to_json().

162 {
163  return ast_json_pack("{s: s, s: s}",
164  "name", name,
165  "state", ast_devstate_str(state));
166 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
const char * ast_devstate_str(enum ast_device_state devstate) attribute_pure
Convert device state to text string that is easier to parse.
Definition: devicestate.c:255
static const char name[]
Definition: cdr_mysql.c:74

◆ stasis_app_device_state_update()

enum stasis_device_state_result stasis_app_device_state_update ( const char *  name,
const char *  value 
)

Changes the state of a device controlled by ARI.

Note
The controlled device must be prefixed with 'Stasis:'.
Implicitly creates the device state.
Parameters
namethe name of the ARI controlled device
valuea valid device state value
Returns
a stasis device state application result.

Definition at line 211 of file res_stasis_device_state.c.

References ast_db_put(), ast_debug, AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_devstate_val(), ast_log, ast_strlen_zero, DEVICE_STATE_FAMILY, DEVICE_STATE_SCHEME_STASIS, LOG_ERROR, STASIS_DEVICE_STATE_MISSING, STASIS_DEVICE_STATE_NOT_CONTROLLED, STASIS_DEVICE_STATE_OK, STASIS_DEVICE_STATE_UNKNOWN, and state.

Referenced by ast_ari_device_states_update().

213 {
214  size_t size = strlen(DEVICE_STATE_SCHEME_STASIS);
215  enum ast_device_state state;
216 
217  ast_debug(3, "Updating device name = %s, value = %s", name, value);
218 
219  if (strncasecmp(name, DEVICE_STATE_SCHEME_STASIS, size)) {
220  ast_log(LOG_ERROR, "Update can only be used to set "
221  "'%s' device state!\n", DEVICE_STATE_SCHEME_STASIS);
223  }
224 
225  name += size;
226  if (ast_strlen_zero(name)) {
227  ast_log(LOG_ERROR, "Update requires custom device name!\n");
229  }
230 
231  if (!value || (state = ast_devstate_val(value)) == AST_DEVICE_UNKNOWN) {
232  ast_log(LOG_ERROR, "Unknown device state "
233  "value '%s'\n", value);
235  }
236 
240 
241  return STASIS_DEVICE_STATE_OK;
242 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
ast_device_state
Device States.
Definition: devicestate.h:52
#define DEVICE_STATE_SCHEME_STASIS
int value
Definition: syslog.c:37
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510
enum ast_device_state ast_devstate_val(const char *val)
Convert device state from text to integer value.
Definition: devicestate.c:260
#define LOG_ERROR
Definition: logger.h:285
static const char name[]
Definition: cdr_mysql.c:74
#define DEVICE_STATE_FAMILY
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
Definition: main/db.c:327

◆ stasis_app_device_states_to_json()

struct ast_json* stasis_app_device_states_to_json ( void  )

Convert device states to json array.

Returns
JSON representation.
NULL on error.

Definition at line 168 of file res_stasis_device_state.c.

References array(), ast_db_freetree(), ast_db_gettree(), ast_json_array_append(), ast_json_array_create(), ast_strlen_zero, DEVICE_STATE_FAMILY, DEVICE_STATE_SCHEME_STASIS, DEVICE_STATE_SIZE, ast_db_entry::key, name, ast_db_entry::next, NULL, and stasis_app_device_state_to_json().

Referenced by ast_ari_device_states_list().

169 {
171  struct ast_db_entry *tree;
172  struct ast_db_entry *entry;
173 
175  for (entry = tree; entry; entry = entry->next) {
176  const char *name = strrchr(entry->key, '/');
177 
178  if (!ast_strlen_zero(name)) {
179  char device[DEVICE_STATE_SIZE];
180 
181  snprintf(device, sizeof(device), "%s%s", DEVICE_STATE_SCHEME_STASIS, ++name);
182  ast_json_array_append(array,
184  }
185  }
186  ast_db_freetree(tree);
187 
188  return array;
189 }
ast_device_state
Device States.
Definition: devicestate.h:52
#define DEVICE_STATE_SCHEME_STASIS
#define DEVICE_STATE_SIZE
void ast_db_freetree(struct ast_db_entry *entry)
Free structure created by ast_db_gettree()
Definition: main/db.c:598
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_db_entry * next
Definition: astdb.h:32
struct ast_json * ast_json_array_create(void)
Create a empty JSON array.
Definition: json.c:352
int ast_json_array_append(struct ast_json *array, struct ast_json *value)
Append to an array.
Definition: json.c:368
struct ast_db_entry * ast_db_gettree(const char *family, const char *keytree)
Get a list of values within the astdb tree.
Definition: main/db.c:531
static int array(struct ast_channel *chan, const char *cmd, char *var, const char *value)
Definition: astdb.h:31
static const char name[]
Definition: cdr_mysql.c:74
struct ast_json * stasis_app_device_state_to_json(const char *name, enum ast_device_state state)
Convert device state to json.
#define DEVICE_STATE_FAMILY
Abstract JSON element (object, array, string, int, ...).
Definition: search.h:40
char * key
Definition: astdb.h:33

◆ stasis_device_state_cb()

static enum ast_device_state stasis_device_state_cb ( const char *  data)
static

Definition at line 292 of file res_stasis_device_state.c.

References ast_db_get(), ast_devstate_val(), buf, DEVICE_STATE_FAMILY, and DEVICE_STATE_SIZE.

Referenced by load_module().

293 {
294  char buf[DEVICE_STATE_SIZE];
295 
296  ast_db_get(DEVICE_STATE_FAMILY, data, buf, sizeof(buf));
297 
298  return ast_devstate_val(buf);
299 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define DEVICE_STATE_SIZE
enum ast_device_state ast_devstate_val(const char *val)
Convert device state from text to integer value.
Definition: devicestate.c:260
char data[0]
Definition: astdb.h:34
int ast_db_get(const char *family, const char *key, char *value, int valuelen)
Get key value specified by family/key.
Definition: main/db.c:412
#define DEVICE_STATE_FAMILY

◆ subscribe_device_state()

static int subscribe_device_state ( struct stasis_app app,
void *  obj 
)
static

Definition at line 360 of file res_stasis_device_state.c.

References ao2_bump, ao2_link_flags, ao2_lock, ao2_ref, ao2_unlock, ast_debug, ast_device_state_message_type(), ast_device_state_topic(), ast_device_state_topic_all(), ast_log, device_state_subscription::device_name, DEVICE_STATE_ALL, device_state_cb(), device_state_subscription_create(), is_subscribed_device_state(), LOG_ERROR, NULL, OBJ_NOLOCK, stasis_app_name(), stasis_subscribe_pool, stasis_subscription_accept_message_type(), stasis_subscription_change_type(), STASIS_SUBSCRIPTION_FILTER_SELECTIVE, stasis_subscription_set_filter(), and device_state_subscription::sub.

361 {
362  struct device_state_subscription *sub = obj;
363  struct stasis_topic *topic;
364 
365  if (!sub) {
367  if (!sub) {
368  return -1;
369  }
370  }
371 
372  if (strcmp(sub->device_name, DEVICE_STATE_ALL)) {
373  topic = ast_device_state_topic(sub->device_name);
374  } else {
375  topic = ast_device_state_topic_all();
376  }
377 
379 
380  if (is_subscribed_device_state(app, sub->device_name)) {
382  ast_debug(3, "App %s is already subscribed to %s\n", stasis_app_name(app), sub->device_name);
383  return 0;
384  }
385 
386  ast_debug(3, "Subscribing to device %s\n", sub->device_name);
387 
388  sub->sub = stasis_subscribe_pool(topic, device_state_cb, ao2_bump(sub));
389  if (!sub->sub) {
391  ast_log(LOG_ERROR, "Unable to subscribe to device %s\n",
392  sub->device_name);
393  /* Reference we added when attempting to stasis_subscribe_pool */
394  ao2_ref(sub, -1);
395  return -1;
396  }
400 
403 
404  return 0;
405 }
struct stasis_topic * ast_device_state_topic(const char *device)
Get the Stasis topic for device state messages for a specific device.
Definition: devicestate.c:683
static struct ao2_container * device_state_subscriptions
Device state subscription object.
const ast_string_field device_name
#define DEVICE_STATE_ALL
Assume that the ao2_container is already locked.
Definition: astobj2.h:1067
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
Definition: stasis.c:1079
#define ao2_link_flags(container, obj, flags)
Definition: astobj2.h:1572
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
static struct device_state_subscription * device_state_subscription_create(const struct stasis_app *app, const char *device_name)
#define ao2_bump(obj)
Definition: astobj2.h:491
struct stasis_message_type * ast_device_state_message_type(void)
Get the Stasis message type for device state messages.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static void device_state_cb(void *data, struct stasis_subscription *sub, struct stasis_message *msg)
const char * stasis_app_name(const struct stasis_app *app)
Retrieve an application's name.
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
static int is_subscribed_device_state(struct stasis_app *app, const char *name)
#define LOG_ERROR
Definition: logger.h:285
#define stasis_subscribe_pool(topic, callback, data)
Definition: stasis.h:682
struct stasis_topic * ast_device_state_topic_all(void)
Get the Stasis topic for device state messages.
Definition: devicestate.c:668
struct stasis_subscription * sub
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
Definition: stasis.c:1025
struct stasis_forward * sub
Definition: res_corosync.c:240
struct stasis_message_type * stasis_subscription_change_type(void)
Gets the message type for subscription change notices.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 476 of file res_stasis_device_state.c.

References ao2_cleanup, ast_devstate_prov_del(), AST_MODFLAG_GLOBAL_SYMBOLS, AST_MODULE_INFO(), AST_MODULE_SUPPORT_CORE, ASTERISK_GPL_KEY, DEVICE_STATE_PROVIDER_STASIS, load_module(), NULL, and stasis_app_unregister_event_source().

477 {
482  return 0;
483 }
static struct ao2_container * device_state_subscriptions
int ast_devstate_prov_del(const char *label)
Remove device state provider.
Definition: devicestate.c:418
#define NULL
Definition: resample.c:96
struct stasis_app_event_source device_state_event_source
#define DEVICE_STATE_PROVIDER_STASIS
void stasis_app_unregister_event_source(struct stasis_app_event_source *obj)
Unregister an application event source.
Definition: res_stasis.c:1823
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ unsubscribe_device_state()

static int unsubscribe_device_state ( struct stasis_app app,
const char *  name 
)
static

Definition at line 407 of file res_stasis_device_state.c.

References ao2_cleanup, ao2_lock, ao2_unlock, find_device_state_subscription(), remove_device_state_subscription(), and device_state_subscription::sub.

408 {
410 
413  if (sub) {
415  }
417 
418  ao2_cleanup(sub);
419 
420  return 0;
421 }
static struct ao2_container * device_state_subscriptions
Device state subscription object.
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ao2_lock(a)
Definition: astobj2.h:718
static void remove_device_state_subscription(struct device_state_subscription *sub)
static struct device_state_subscription * find_device_state_subscription(struct stasis_app *app, const char *name)
static const char name[]
Definition: cdr_mysql.c:74
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct stasis_forward * sub
Definition: res_corosync.c:240

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "Stasis application device state support" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .requires = "res_stasis", }
static

Definition at line 490 of file res_stasis_device_state.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 490 of file res_stasis_device_state.c.

◆ device_state_event_source

struct stasis_app_event_source device_state_event_source

Definition at line 447 of file res_stasis_device_state.c.

◆ device_state_subscriptions

struct ao2_container* device_state_subscriptions
static

Container for subscribed device states

Definition at line 49 of file res_stasis_device_state.c.