Asterisk - The Open Source Telephony Project  GIT-master-e8cda4b
Data Structures | Typedefs | Functions
ari.h File Reference

Asterisk RESTful API hooks. More...

#include "asterisk/http.h"
#include "asterisk/json.h"

Go to the source code of this file.

Data Structures

struct  ast_ari_response
 
struct  stasis_rest_handlers
 Handler for a single RESTful path segment. More...
 

Typedefs

typedef void(* stasis_rest_callback) (struct ast_tcptls_session_instance *ser, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
 Callback type for RESTful method handlers. More...
 

Functions

int ast_ari_add_handler (struct stasis_rest_handlers *handler)
 
void ast_ari_get_docs (const char *uri, const char *prefix, struct ast_variable *headers, struct ast_ari_response *response)
 
void ast_ari_invoke (struct ast_tcptls_session_instance *ser, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
 
enum ast_json_encoding_format ast_ari_json_format (void)
 Configured encoding format for JSON output. More...
 
struct ast_jsonast_ari_oom_json (void)
 The stock message to return when out of memory. More...
 
int ast_ari_remove_handler (struct stasis_rest_handlers *handler)
 
void ast_ari_response_accepted (struct ast_ari_response *response)
 Fill in a Accepted (202) ast_ari_response. More...
 
void ast_ari_response_alloc_failed (struct ast_ari_response *response)
 Fill in response with a 500 message for allocation failures. More...
 
void ast_ari_response_created (struct ast_ari_response *response, const char *url, struct ast_json *message)
 Fill in a Created (201) ast_ari_response. More...
 
void ast_ari_response_error (struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
 Fill in an error ast_ari_response. More...
 
void ast_ari_response_no_content (struct ast_ari_response *response)
 Fill in a No Content (204) ast_ari_response. More...
 
void ast_ari_response_ok (struct ast_ari_response *response, struct ast_json *message)
 Fill in an OK (200) ast_ari_response. More...
 
struct ast_ari_websocket_sessionast_ari_websocket_session_create (struct ast_websocket *ws_session, int(*validator)(struct ast_json *))
 Create an ARI WebSocket session. More...
 
struct ast_sockaddrast_ari_websocket_session_get_remote_addr (struct ast_ari_websocket_session *session)
 Get the remote address from an ARI WebSocket. More...
 
const char * ast_ari_websocket_session_id (const struct ast_ari_websocket_session *session)
 Get the Session ID for an ARI WebSocket. More...
 
struct ast_jsonast_ari_websocket_session_read (struct ast_ari_websocket_session *session)
 Read a message from an ARI WebSocket. More...
 
int ast_ari_websocket_session_write (struct ast_ari_websocket_session *session, struct ast_json *message)
 Send a message to an ARI WebSocket. More...
 

Detailed Description

Asterisk RESTful API hooks.

This header file is used mostly as glue code between generated declarations and res_ari.c.

Author
David M. Lee, II dlee@.nosp@m.digi.nosp@m.um.co.nosp@m.m

Definition in file ari.h.

Typedef Documentation

◆ stasis_rest_callback

typedef void(* stasis_rest_callback) (struct ast_tcptls_session_instance *ser, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)

Callback type for RESTful method handlers.

Parameters
serTCP/TLS session object
get_paramsGET parameters from the HTTP request.
path_varsPath variables from any wildcard path segments.
headersHTTP headers from the HTTP requiest.
[out]responseThe RESTful response.

Definition at line 59 of file ari.h.

Function Documentation

◆ ast_ari_add_handler()

int ast_ari_add_handler ( struct stasis_rest_handlers handler)

Add a resource for REST handling.

Parameters
handlerHandler to add.
Returns
0 on success.
non-zero on failure.

Definition at line 179 of file res_ari.c.

References ao2_alloc, ao2_cleanup, ao2_ref, handler(), lock, NULL, stasis_rest_handlers::num_children, RAII_VAR, and SCOPED_MUTEX.

Referenced by load_module(), and setup_invocation_test().

180 {
181  RAII_VAR(struct stasis_rest_handlers *, new_handler, NULL, ao2_cleanup);
182  size_t old_size, new_size;
183 
185 
186  old_size = sizeof(*new_handler) + root_handler->num_children * sizeof(handler);
187  new_size = old_size + sizeof(handler);
188 
189  new_handler = ao2_alloc(new_size, NULL);
190  if (!new_handler) {
191  return -1;
192  }
193  memcpy(new_handler, root_handler, old_size);
194  new_handler->children[new_handler->num_children++] = handler;
195 
197  ao2_ref(new_handler, +1);
198  root_handler = new_handler;
199  return 0;
200 }
#define NULL
Definition: resample.c:96
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:587
#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
ast_mutex_t lock
Definition: app_meetme.c:1091
static struct stasis_rest_handlers * root_handler
Definition: res_ari.c:169
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
size_t num_children
Definition: ari.h:83
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static void handler(const char *name, int response_code, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Definition: test_ari.c:59
static ast_mutex_t root_handler_lock
Definition: res_ari.c:166
Handler for a single RESTful path segment.
Definition: ari.h:68

◆ ast_ari_get_docs()

void ast_ari_get_docs ( const char *  uri,
const char *  prefix,
struct ast_variable headers,
struct ast_ari_response response 
)

Definition at line 598 of file res_ari.c.

References ast_ari_response_alloc_failed(), ast_ari_response_error(), ast_ari_response_ok(), ast_begins_with(), ast_config_AST_DATA_DIR, ast_debug, ast_free, ast_json_load_new_file(), ast_json_object_del(), ast_json_object_get(), ast_json_object_set(), ast_json_stringf(), ast_log, ast_std_free(), ast_str_append(), ast_str_buffer(), ast_str_create, ast_json_error::column, errno, host, ast_json_error::line, LOG_ERROR, ast_variable::name, ast_variable::next, NULL, RAII_VAR, ast_json_error::source, ast_json_error::text, and ast_variable::value.

Referenced by ast_ari_callback(), and AST_TEST_DEFINE().

600 {
601  RAII_VAR(struct ast_str *, absolute_path_builder, NULL, ast_free);
602  RAII_VAR(char *, absolute_api_dirname, NULL, ast_std_free);
603  RAII_VAR(char *, absolute_filename, NULL, ast_std_free);
604  struct ast_json *obj = NULL;
605  struct ast_variable *host = NULL;
606  struct ast_json_error error = {};
607  struct stat file_stat;
608 
609  ast_debug(3, "%s(%s)\n", __func__, uri);
610 
611  absolute_path_builder = ast_str_create(80);
612  if (absolute_path_builder == NULL) {
614  return;
615  }
616 
617  /* absolute path to the rest-api directory */
618  ast_str_append(&absolute_path_builder, 0, "%s", ast_config_AST_DATA_DIR);
619  ast_str_append(&absolute_path_builder, 0, "/rest-api/");
620  absolute_api_dirname = realpath(ast_str_buffer(absolute_path_builder), NULL);
621  if (absolute_api_dirname == NULL) {
622  ast_log(LOG_ERROR, "Error determining real directory for rest-api\n");
624  response, 500, "Internal Server Error",
625  "Cannot find rest-api directory");
626  return;
627  }
628 
629  /* absolute path to the requested file */
630  ast_str_append(&absolute_path_builder, 0, "%s", uri);
631  absolute_filename = realpath(ast_str_buffer(absolute_path_builder), NULL);
632  if (absolute_filename == NULL) {
633  switch (errno) {
634  case ENAMETOOLONG:
635  case ENOENT:
636  case ENOTDIR:
638  response, 404, "Not Found",
639  "Resource not found");
640  break;
641  case EACCES:
643  response, 403, "Forbidden",
644  "Permission denied");
645  break;
646  default:
648  "Error determining real path for uri '%s': %s\n",
649  uri, strerror(errno));
651  response, 500, "Internal Server Error",
652  "Cannot find file");
653  break;
654  }
655  return;
656  }
657 
658  if (!ast_begins_with(absolute_filename, absolute_api_dirname)) {
659  /* HACKERZ! */
661  "Invalid attempt to access '%s' (not in %s)\n",
662  absolute_filename, absolute_api_dirname);
664  response, 404, "Not Found",
665  "Resource not found");
666  return;
667  }
668 
669  if (stat(absolute_filename, &file_stat) == 0) {
670  if (!(file_stat.st_mode & S_IFREG)) {
671  /* Not a file */
673  response, 403, "Forbidden",
674  "Invalid access");
675  return;
676  }
677  } else {
678  /* Does not exist */
680  response, 404, "Not Found",
681  "Resource not found");
682  return;
683  }
684 
685  /* Load resource object from file */
686  obj = ast_json_load_new_file(absolute_filename, &error);
687  if (obj == NULL) {
688  ast_log(LOG_ERROR, "Error parsing resource file: %s:%d(%d) %s\n",
689  error.source, error.line, error.column, error.text);
691  response, 500, "Internal Server Error",
692  "Yikes! Cannot parse resource");
693  return;
694  }
695 
696  /* Update the basePath properly */
697  if (ast_json_object_get(obj, "basePath") != NULL) {
698  for (host = headers; host; host = host->next) {
699  if (strcasecmp(host->name, "Host") == 0) {
700  break;
701  }
702  }
703  if (host != NULL) {
704  if (prefix != NULL && strlen(prefix) > 0) {
706  obj, "basePath",
707  ast_json_stringf("http://%s%s/ari", host->value,prefix));
708  } else {
710  obj, "basePath",
711  ast_json_stringf("http://%s/ari", host->value));
712  }
713  } else {
714  /* Without the host, we don't have the basePath */
715  ast_json_object_del(obj, "basePath");
716  }
717  }
718 
719  ast_ari_response_ok(response, obj);
720 }
struct ast_variable * next
void ast_std_free(void *ptr)
Definition: astmm.c:1766
void ast_ari_response_ok(struct ast_ari_response *response, struct ast_json *message)
Fill in an OK (200) ast_ari_response.
Definition: res_ari.c:276
char text[AST_JSON_ERROR_TEXT_LENGTH]
Definition: json.h:837
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_json_object_del(struct ast_json *object, const char *key)
Delete a field from a JSON object.
Definition: json.c:408
void ast_ari_response_alloc_failed(struct ast_ari_response *response)
Fill in response with a 500 message for allocation failures.
Definition: res_ari.c:298
Structure for variables, used for configurations and for channel variables.
struct ast_json * ast_json_stringf(const char *format,...)
Create a JSON string, printf style.
Definition: json.c:283
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define NULL
Definition: resample.c:96
JSON parsing error information.
Definition: json.h:829
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
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
static char host[256]
Definition: muted.c:77
#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
const char * ast_config_AST_DATA_DIR
Definition: options.c:158
#define LOG_ERROR
Definition: logger.h:285
struct ast_json * ast_json_load_new_file(const char *path, struct ast_json_error *error)
Parse file at path into JSON object or array.
Definition: json.c:583
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
int column
Definition: json.h:833
int errno
#define ast_free(a)
Definition: astmm.h:182
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
char source[AST_JSON_ERROR_TEXT_LENGTH]
Definition: json.h:839
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:397
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Definition: strings.h:94
Abstract JSON element (object, array, string, int, ...).
int error(const char *format,...)
Definition: utils/frame.c:999
int line
Definition: json.h:831
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:620
static char prefix[MAX_PREFIX]
Definition: http.c:141

◆ ast_ari_invoke()

void ast_ari_invoke ( struct ast_tcptls_session_instance ser,
const char *  uri,
enum ast_http_method  method,
struct ast_variable get_params,
struct ast_variable headers,
struct ast_json body,
struct ast_ari_response response 
)

Definition at line 491 of file res_ari.c.

References add_allow_header(), ao2_cleanup, ari_handle_websocket(), ast_ari_response_error(), ast_assert, ast_debug, ast_get_http_method(), AST_HTTP_GET, AST_HTTP_MAX_METHOD, AST_HTTP_OPTIONS, ast_log, ast_strdupa, ast_uri_decode(), ast_uri_http_legacy, ast_variable_new, ast_variables_destroy(), stasis_rest_handlers::callbacks, stasis_rest_handlers::children, get_root_handler(), handle_options(), handler(), stasis_rest_handlers::is_wildcard, LOG_ERROR, ast_ari_response::message, method, ast_variable::next, ast_ari_response::no_response, NULL, stasis_rest_handlers::num_children, stasis_rest_handlers::path_segment, RAII_VAR, ast_ari_response::response_code, strsep(), and stasis_rest_handlers::ws_server.

Referenced by ast_ari_callback(), and AST_TEST_DEFINE().

495 {
496  RAII_VAR(struct stasis_rest_handlers *, root, NULL, ao2_cleanup);
498  struct stasis_rest_handlers *wildcard_handler = NULL;
499  RAII_VAR(struct ast_variable *, path_vars, NULL, ast_variables_destroy);
500  char *path = ast_strdupa(uri);
501  char *path_segment;
502  stasis_rest_callback callback;
503 
504  root = handler = get_root_handler();
505  ast_assert(root != NULL);
506 
507  ast_debug(3, "Finding handler for %s\n", path);
508 
509  while ((path_segment = strsep(&path, "/")) && (strlen(path_segment) > 0)) {
510  struct stasis_rest_handlers *found_handler = NULL;
511  int i;
512 
513  ast_uri_decode(path_segment, ast_uri_http_legacy);
514  ast_debug(3, " Finding handler for %s\n", path_segment);
515 
516  for (i = 0; found_handler == NULL && i < handler->num_children; ++i) {
517  struct stasis_rest_handlers *child = handler->children[i];
518 
519  if (child->is_wildcard) {
520  /* Record the path variable */
521  struct ast_variable *path_var = ast_variable_new(child->path_segment, path_segment, __FILE__);
522  path_var->next = path_vars;
523  path_vars = path_var;
524  wildcard_handler = child;
525  ast_debug(3, " Checking %s %s: Matched wildcard.\n", handler->path_segment, child->path_segment);
526 
527  } else if (strcmp(child->path_segment, path_segment) == 0) {
528  found_handler = child;
529  ast_debug(3, " Checking %s %s: Explicit match with %s\n", handler->path_segment, child->path_segment, path_segment);
530  } else {
531  ast_debug(3, " Checking %s %s: Didn't match %s\n", handler->path_segment, child->path_segment, path_segment);
532  }
533  }
534 
535  if (!found_handler && wildcard_handler) {
536  ast_debug(3, " No explicit handler found for %s. Using wildcard %s.\n",
537  path_segment, wildcard_handler->path_segment);
538  found_handler = wildcard_handler;
539  wildcard_handler = NULL;
540  }
541 
542  if (found_handler == NULL) {
543  /* resource not found */
544  ast_debug(3, " Handler not found for %s\n", path_segment);
546  response, 404, "Not Found",
547  "Resource not found");
548  return;
549  } else {
550  handler = found_handler;
551  }
552  }
553 
554  ast_assert(handler != NULL);
555  if (method == AST_HTTP_OPTIONS) {
556  handle_options(handler, headers, response);
557  return;
558  }
559 
560  if (method < 0 || method >= AST_HTTP_MAX_METHOD) {
561  add_allow_header(handler, response);
563  response, 405, "Method Not Allowed",
564  "Invalid method");
565  return;
566  }
567 
568  if (handler->ws_server && method == AST_HTTP_GET) {
569  /* WebSocket! */
570  ari_handle_websocket(handler->ws_server, ser, uri, method,
571  get_params, headers);
572  /* Since the WebSocket code handles the connection, we shouldn't
573  * do anything else; setting no_response */
574  response->no_response = 1;
575  return;
576  }
577 
578  callback = handler->callbacks[method];
579  if (callback == NULL) {
580  add_allow_header(handler, response);
582  response, 405, "Method Not Allowed",
583  "Invalid method");
584  return;
585  }
586 
587  callback(ser, get_params, path_vars, headers, body, response);
588  if (response->message == NULL && response->response_code == 0) {
589  /* Really should not happen */
590  ast_log(LOG_ERROR, "ARI %s %s not implemented\n",
593  response, 501, "Not Implemented",
594  "Method not implemented");
595  }
596 }
void ast_uri_decode(char *s, struct ast_flags spec)
Decode URI, URN, URL (overwrite string)
Definition: main/utils.c:616
struct ast_variable * next
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
void ari_handle_websocket(struct ast_websocket_server *ws_server, struct ast_tcptls_session_instance *ser, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers)
Wrapper for invoking the websocket code for an incoming connection.
Structure for variables, used for configurations and for channel variables.
#define ast_assert(a)
Definition: utils.h:710
static struct stasis_rest_handlers * get_root_handler(void)
Definition: res_ari.c:238
#define NULL
Definition: resample.c:96
int response_code
Definition: ari.h:98
static void handle_options(struct stasis_rest_handlers *handler, struct ast_variable *headers, struct ast_ari_response *response)
Handle OPTIONS request, mainly for CORS preflight requests.
Definition: res_ari.c:361
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#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
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const char * method
Definition: res_pjsip.c:4335
#define ast_variable_new(name, value, filename)
struct ast_websocket_server * ws_server
Definition: ari.h:81
#define LOG_ERROR
Definition: logger.h:285
const struct ast_flags ast_uri_http_legacy
Definition: main/utils.c:574
size_t num_children
Definition: ari.h:83
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
const char * ast_get_http_method(enum ast_http_method method) attribute_pure
Return http method name string.
Definition: http.c:190
void(* stasis_rest_callback)(struct ast_tcptls_session_instance *ser, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Callback type for RESTful method handlers.
Definition: ari.h:59
struct ast_json * message
Definition: ari.h:93
const char * path_segment
Definition: ari.h:70
char * strsep(char **str, const char *delims)
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct stasis_rest_handlers * children[]
Definition: ari.h:85
static void add_allow_header(struct stasis_rest_handlers *handler, struct ast_ari_response *response)
Definition: res_ari.c:315
static void handler(const char *name, int response_code, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Definition: test_ari.c:59
stasis_rest_callback callbacks[AST_HTTP_MAX_METHOD]
Definition: ari.h:79
unsigned int no_response
Definition: ari.h:104
Handler for a single RESTful path segment.
Definition: ari.h:68

◆ ast_ari_json_format()

enum ast_json_encoding_format ast_ari_json_format ( void  )

Configured encoding format for JSON output.

Returns
JSON output encoding (compact, pretty, etc.)

Definition at line 806 of file res_ari.c.

References ao2_cleanup, ast_ari_config_get(), NULL, and RAII_VAR.

Referenced by ast_ari_callback(), ast_ari_websocket_session_write(), and stasis_app_message_handler().

807 {
808  RAII_VAR(struct ast_ari_conf *, cfg, NULL, ao2_cleanup);
809  cfg = ast_ari_config_get();
810  return cfg->general->format;
811 }
struct ast_ari_conf * ast_ari_config_get(void)
Get the current ARI configuration.
All configuration options for ARI.
Definition: internal.h:54
#define NULL
Definition: resample.c:96
#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
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ ast_ari_oom_json()

struct ast_json* ast_ari_oom_json ( void  )

The stock message to return when out of memory.

The refcount is NOT bumped on this object, so ast_json_ref() if you want to keep the reference.

Returns
JSON message specifying an out-of-memory error.

Definition at line 174 of file res_ari.c.

References oom_json.

175 {
176  return oom_json;
177 }
static struct ast_json * oom_json
Definition: res_ari.c:172

◆ ast_ari_remove_handler()

int ast_ari_remove_handler ( struct stasis_rest_handlers handler)

Remove a resource for REST handling.

Parameters
handlerHandler to add.
Returns
0 on success.
non-zero on failure.

Definition at line 202 of file res_ari.c.

References ao2_alloc, ao2_cleanup, ast_assert, ast_mutex_lock, ast_mutex_unlock, stasis_rest_handlers::children, handler(), NULL, and stasis_rest_handlers::num_children.

Referenced by tear_down_invocation_test(), and unload_module().

203 {
204  struct stasis_rest_handlers *new_handler;
205  size_t size;
206  size_t i;
207  size_t j;
208 
210 
212  size = sizeof(*new_handler) + root_handler->num_children * sizeof(handler);
213 
214  new_handler = ao2_alloc(size, NULL);
215  if (!new_handler) {
217  return -1;
218  }
219 
220  /* Create replacement root_handler less the handler to remove. */
221  memcpy(new_handler, root_handler, sizeof(*new_handler));
222  for (i = 0, j = 0; i < root_handler->num_children; ++i) {
223  if (root_handler->children[i] == handler) {
224  continue;
225  }
226  new_handler->children[j++] = root_handler->children[i];
227  }
228  new_handler->num_children = j;
229 
230  /* Replace the old root_handler with the new. */
232  root_handler = new_handler;
233 
235  return 0;
236 }
#define ast_assert(a)
Definition: utils.h:710
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static struct stasis_rest_handlers * root_handler
Definition: res_ari.c:169
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
size_t num_children
Definition: ari.h:83
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct stasis_rest_handlers * children[]
Definition: ari.h:85
static void handler(const char *name, int response_code, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Definition: test_ari.c:59
static ast_mutex_t root_handler_lock
Definition: res_ari.c:166
Handler for a single RESTful path segment.
Definition: ari.h:68
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ ast_ari_response_accepted()

void ast_ari_response_accepted ( struct ast_ari_response response)

Fill in a Accepted (202) ast_ari_response.

Definition at line 291 of file res_ari.c.

References ast_json_null(), ast_ari_response::message, ast_ari_response::response_code, and ast_ari_response::response_text.

Referenced by ast_ari_asterisk_reload_module().

292 {
293  response->message = ast_json_null();
294  response->response_code = 202;
295  response->response_text = "Accepted";
296 }
int response_code
Definition: ari.h:98
struct ast_json * ast_json_null(void)
Get the JSON null value.
Definition: json.c:248
const char * response_text
Definition: ari.h:102
struct ast_json * message
Definition: ari.h:93

◆ ast_ari_response_alloc_failed()

void ast_ari_response_alloc_failed ( struct ast_ari_response response)

Fill in response with a 500 message for allocation failures.

Parameters
responseResponse to fill in.

Definition at line 298 of file res_ari.c.

References ast_json_ref(), ast_ari_response::message, ast_ari_response::response_code, and ast_ari_response::response_text.

Referenced by ari_bridges_play_helper(), ari_bridges_play_new(), ari_channels_handle_originate_with_id(), ast_ari_applications_subscribe_cb(), ast_ari_applications_unsubscribe_cb(), ast_ari_asterisk_add_log_cb(), ast_ari_asterisk_get_global_var(), ast_ari_asterisk_get_global_var_cb(), ast_ari_asterisk_get_info(), ast_ari_asterisk_get_info_cb(), ast_ari_asterisk_get_module(), ast_ari_asterisk_list_modules(), ast_ari_asterisk_set_global_var_cb(), ast_ari_asterisk_update_object(), ast_ari_bridges_add_channel(), ast_ari_bridges_add_channel_cb(), ast_ari_bridges_create_cb(), ast_ari_bridges_create_with_id_cb(), ast_ari_bridges_list(), ast_ari_bridges_play_cb(), ast_ari_bridges_play_with_id_cb(), ast_ari_bridges_record(), ast_ari_bridges_record_cb(), ast_ari_bridges_remove_channel_cb(), ast_ari_bridges_start_moh(), ast_ari_bridges_start_moh_cb(), ast_ari_channels_continue_in_dialplan(), ast_ari_channels_continue_in_dialplan_cb(), ast_ari_channels_create(), ast_ari_channels_dial(), ast_ari_channels_dial_cb(), ast_ari_channels_get_channel_var(), ast_ari_channels_get_channel_var_cb(), ast_ari_channels_hangup_cb(), ast_ari_channels_list(), ast_ari_channels_move_cb(), ast_ari_channels_mute_cb(), ast_ari_channels_play_cb(), ast_ari_channels_play_with_id_cb(), ast_ari_channels_record_cb(), ast_ari_channels_redirect_cb(), ast_ari_channels_send_dtmf_cb(), ast_ari_channels_set_channel_var_cb(), ast_ari_channels_snoop_channel_cb(), ast_ari_channels_snoop_channel_with_id_cb(), ast_ari_channels_start_moh_cb(), ast_ari_channels_unmute_cb(), ast_ari_device_states_update_cb(), ast_ari_endpoints_get(), ast_ari_endpoints_list(), ast_ari_endpoints_list_by_tech(), ast_ari_events_event_websocket_ws_attempted_cb(), ast_ari_events_event_websocket_ws_established_cb(), ast_ari_events_user_event_cb(), ast_ari_get_docs(), ast_ari_mailboxes_update_cb(), ast_ari_playbacks_control_cb(), ast_ari_recordings_copy_stored_cb(), ast_ari_recordings_list_stored(), ast_ari_sounds_list_cb(), control_list_create(), handle_options(), json_to_ast_variables(), return_sorcery_object(), and send_message().

299 {
300  response->message = ast_json_ref(oom_json);
301  response->response_code = 500;
302  response->response_text = "Internal Server Error";
303 }
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
int response_code
Definition: ari.h:98
static struct ast_json * oom_json
Definition: res_ari.c:172
const char * response_text
Definition: ari.h:102
struct ast_json * message
Definition: ari.h:93

◆ ast_ari_response_created()

void ast_ari_response_created ( struct ast_ari_response response,
const char *  url,
struct ast_json message 
)

Fill in a Created (201) ast_ari_response.

Parameters
responseResponse to fill in.
urlURL to the created resource.
messageJSON response. This reference is stolen, so just ast_json_ref if you need to keep a reference to it.

Definition at line 305 of file res_ari.c.

References ao2_cleanup, ast_str_append(), get_root_handler(), ast_ari_response::headers, ast_ari_response::message, RAII_VAR, ast_ari_response::response_code, and ast_ari_response::response_text.

Referenced by ari_bridges_play_found(), ari_bridges_play_new(), ari_channels_handle_play(), ast_ari_bridges_record(), and ast_ari_channels_record().

307 {
309  response->message = message;
310  response->response_code = 201;
311  response->response_text = "Created";
312  ast_str_append(&response->headers, 0, "Location: /%s%s\r\n", root->path_segment, url);
313 }
struct ast_str * headers
Definition: ari.h:95
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
static struct stasis_rest_handlers * get_root_handler(void)
Definition: res_ari.c:238
int response_code
Definition: ari.h:98
#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
const char * response_text
Definition: ari.h:102
struct ast_json * message
Definition: ari.h:93
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static char url[512]
Handler for a single RESTful path segment.
Definition: ari.h:68

◆ ast_ari_response_error()

void ast_ari_response_error ( struct ast_ari_response response,
int  response_code,
const char *  response_text,
const char *  message_fmt,
  ... 
)

Fill in an error ast_ari_response.

Parameters
responseResponse to fill in.
response_codeHTTP response code.
response_textText corresponding to the HTTP response code.
message_fmtError message format string.

Definition at line 259 of file res_ari.c.

References ast_json_pack(), ast_json_ref(), ast_json_unref(), ast_json_vstringf(), ast_ari_response::message, NULL, RAII_VAR, ast_ari_response::response_code, and ast_ari_response::response_text.

Referenced by ari_bridges_play_helper(), ari_bridges_play_new(), ari_channels_handle_originate_with_id(), ari_channels_handle_play(), ari_channels_handle_snoop_channel(), ast_ari_applications_filter(), ast_ari_applications_filter_cb(), ast_ari_applications_get(), ast_ari_applications_get_cb(), ast_ari_applications_list(), ast_ari_applications_list_cb(), ast_ari_applications_subscribe(), ast_ari_applications_subscribe_cb(), ast_ari_applications_unsubscribe(), ast_ari_applications_unsubscribe_cb(), ast_ari_asterisk_add_log(), ast_ari_asterisk_add_log_cb(), ast_ari_asterisk_delete_log(), ast_ari_asterisk_delete_log_cb(), ast_ari_asterisk_delete_object(), ast_ari_asterisk_delete_object_cb(), ast_ari_asterisk_get_global_var(), ast_ari_asterisk_get_global_var_cb(), ast_ari_asterisk_get_info_cb(), ast_ari_asterisk_get_module(), ast_ari_asterisk_get_module_cb(), ast_ari_asterisk_get_object(), ast_ari_asterisk_get_object_cb(), ast_ari_asterisk_list_log_channels(), ast_ari_asterisk_list_log_channels_cb(), ast_ari_asterisk_list_modules_cb(), ast_ari_asterisk_load_module(), ast_ari_asterisk_load_module_cb(), ast_ari_asterisk_ping_cb(), ast_ari_asterisk_reload_module(), ast_ari_asterisk_reload_module_cb(), ast_ari_asterisk_rotate_log(), ast_ari_asterisk_rotate_log_cb(), ast_ari_asterisk_set_global_var(), ast_ari_asterisk_set_global_var_cb(), ast_ari_asterisk_unload_module(), ast_ari_asterisk_unload_module_cb(), ast_ari_asterisk_update_object(), ast_ari_asterisk_update_object_cb(), ast_ari_bridges_add_channel_cb(), ast_ari_bridges_clear_video_source_cb(), ast_ari_bridges_create(), ast_ari_bridges_create_cb(), ast_ari_bridges_create_with_id(), ast_ari_bridges_create_with_id_cb(), ast_ari_bridges_destroy_cb(), ast_ari_bridges_get(), ast_ari_bridges_get_cb(), ast_ari_bridges_list_cb(), ast_ari_bridges_play_cb(), ast_ari_bridges_play_with_id_cb(), ast_ari_bridges_record(), ast_ari_bridges_record_cb(), ast_ari_bridges_remove_channel(), ast_ari_bridges_remove_channel_cb(), ast_ari_bridges_set_video_source(), ast_ari_bridges_set_video_source_cb(), ast_ari_bridges_start_moh_cb(), ast_ari_bridges_stop_moh(), ast_ari_bridges_stop_moh_cb(), ast_ari_callback(), ast_ari_channels_answer(), ast_ari_channels_answer_cb(), ast_ari_channels_continue_in_dialplan(), ast_ari_channels_continue_in_dialplan_cb(), ast_ari_channels_create(), ast_ari_channels_create_cb(), ast_ari_channels_dial(), ast_ari_channels_dial_cb(), ast_ari_channels_external_media(), ast_ari_channels_external_media_cb(), ast_ari_channels_get(), ast_ari_channels_get_cb(), ast_ari_channels_get_channel_var(), ast_ari_channels_get_channel_var_cb(), ast_ari_channels_hangup(), ast_ari_channels_hangup_cb(), ast_ari_channels_hold_cb(), ast_ari_channels_list_cb(), ast_ari_channels_move(), ast_ari_channels_move_cb(), ast_ari_channels_mute(), ast_ari_channels_mute_cb(), ast_ari_channels_originate_cb(), ast_ari_channels_originate_with_id_cb(), ast_ari_channels_play_cb(), ast_ari_channels_play_with_id_cb(), ast_ari_channels_record(), ast_ari_channels_record_cb(), ast_ari_channels_redirect(), ast_ari_channels_redirect_cb(), ast_ari_channels_ring_cb(), ast_ari_channels_ring_stop_cb(), ast_ari_channels_rtpstatistics(), ast_ari_channels_rtpstatistics_cb(), ast_ari_channels_send_dtmf(), ast_ari_channels_send_dtmf_cb(), ast_ari_channels_set_channel_var(), ast_ari_channels_set_channel_var_cb(), ast_ari_channels_snoop_channel_cb(), ast_ari_channels_snoop_channel_with_id_cb(), ast_ari_channels_start_moh_cb(), ast_ari_channels_start_silence_cb(), ast_ari_channels_stop_moh_cb(), ast_ari_channels_stop_silence_cb(), ast_ari_channels_unhold_cb(), ast_ari_channels_unmute(), ast_ari_channels_unmute_cb(), ast_ari_device_states_delete(), ast_ari_device_states_delete_cb(), ast_ari_device_states_get(), ast_ari_device_states_get_cb(), ast_ari_device_states_list(), ast_ari_device_states_list_cb(), ast_ari_device_states_update(), ast_ari_device_states_update_cb(), ast_ari_endpoints_get(), ast_ari_endpoints_get_cb(), ast_ari_endpoints_list(), ast_ari_endpoints_list_by_tech(), ast_ari_endpoints_list_by_tech_cb(), ast_ari_endpoints_list_cb(), ast_ari_endpoints_send_message_cb(), ast_ari_endpoints_send_message_to_endpoint(), ast_ari_endpoints_send_message_to_endpoint_cb(), ast_ari_events_event_websocket_ws_attempted_cb(), ast_ari_events_event_websocket_ws_established_cb(), ast_ari_events_user_event(), ast_ari_events_user_event_cb(), ast_ari_get_docs(), ast_ari_invoke(), ast_ari_mailboxes_delete(), ast_ari_mailboxes_delete_cb(), ast_ari_mailboxes_get(), ast_ari_mailboxes_get_cb(), ast_ari_mailboxes_list(), ast_ari_mailboxes_list_cb(), ast_ari_mailboxes_update(), ast_ari_mailboxes_update_cb(), ast_ari_playbacks_control(), ast_ari_playbacks_control_cb(), ast_ari_playbacks_get(), ast_ari_playbacks_get_cb(), ast_ari_playbacks_stop(), ast_ari_playbacks_stop_cb(), ast_ari_recordings_cancel_cb(), ast_ari_recordings_copy_stored(), ast_ari_recordings_copy_stored_cb(), ast_ari_recordings_delete_stored(), ast_ari_recordings_delete_stored_cb(), ast_ari_recordings_get_live(), ast_ari_recordings_get_live_cb(), ast_ari_recordings_get_stored(), ast_ari_recordings_get_stored_cb(), ast_ari_recordings_get_stored_file(), ast_ari_recordings_get_stored_file_cb(), ast_ari_recordings_list_stored_cb(), ast_ari_recordings_mute_cb(), ast_ari_recordings_pause_cb(), ast_ari_recordings_stop_cb(), ast_ari_recordings_unmute_cb(), ast_ari_recordings_unpause_cb(), ast_ari_sounds_get(), ast_ari_sounds_get_cb(), ast_ari_sounds_list(), ast_ari_sounds_list_cb(), channel_state_invalid(), check_add_remove_channel(), control_list_create(), control_recording(), external_media_audiosocket_tcp(), find_bridge(), find_channel_control(), find_control(), json_to_ast_variables(), remove_trailing_slash(), and send_message().

263 {
265  va_list ap;
266 
267  va_start(ap, message_fmt);
268  message = ast_json_vstringf(message_fmt, ap);
269  va_end(ap);
270  response->message = ast_json_pack("{s: o}",
271  "message", ast_json_ref(message));
272  response->response_code = response_code;
273  response->response_text = response_text;
274 }
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
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
#define NULL
Definition: resample.c:96
int response_code
Definition: ari.h:98
#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_vstringf(const char *format, va_list args)
Create a JSON string, vprintf style.
Definition: json.c:293
const char * response_text
Definition: ari.h:102
struct ast_json * message
Definition: ari.h:93
Abstract JSON element (object, array, string, int, ...).

◆ ast_ari_response_no_content()

void ast_ari_response_no_content ( struct ast_ari_response response)

Fill in a No Content (204) ast_ari_response.

Definition at line 284 of file res_ari.c.

References ast_json_null(), ast_ari_response::message, ast_ari_response::response_code, and ast_ari_response::response_text.

Referenced by ast_ari_asterisk_add_log(), ast_ari_asterisk_delete_log(), ast_ari_asterisk_delete_object(), ast_ari_asterisk_load_module(), ast_ari_asterisk_reload_module(), ast_ari_asterisk_rotate_log(), ast_ari_asterisk_set_global_var(), ast_ari_asterisk_unload_module(), ast_ari_bridges_add_channel(), ast_ari_bridges_clear_video_source(), ast_ari_bridges_destroy(), ast_ari_bridges_remove_channel(), ast_ari_bridges_set_video_source(), ast_ari_bridges_start_moh(), ast_ari_bridges_stop_moh(), ast_ari_channels_answer(), ast_ari_channels_continue_in_dialplan(), ast_ari_channels_dial(), ast_ari_channels_hangup(), ast_ari_channels_hold(), ast_ari_channels_move(), ast_ari_channels_mute(), ast_ari_channels_redirect(), ast_ari_channels_ring(), ast_ari_channels_ring_stop(), ast_ari_channels_send_dtmf(), ast_ari_channels_set_channel_var(), ast_ari_channels_start_moh(), ast_ari_channels_start_silence(), ast_ari_channels_stop_moh(), ast_ari_channels_stop_silence(), ast_ari_channels_unhold(), ast_ari_channels_unmute(), ast_ari_device_states_delete(), ast_ari_device_states_update(), ast_ari_events_user_event(), ast_ari_mailboxes_delete(), ast_ari_mailboxes_update(), ast_ari_playbacks_control(), ast_ari_playbacks_stop(), ast_ari_recordings_delete_stored(), control_recording(), and handle_options().

285 {
286  response->message = ast_json_null();
287  response->response_code = 204;
288  response->response_text = "No Content";
289 }
int response_code
Definition: ari.h:98
struct ast_json * ast_json_null(void)
Get the JSON null value.
Definition: json.c:248
const char * response_text
Definition: ari.h:102
struct ast_json * message
Definition: ari.h:93

◆ ast_ari_response_ok()

void ast_ari_response_ok ( struct ast_ari_response response,
struct ast_json message 
)

Fill in an OK (200) ast_ari_response.

Parameters
responseResponse to fill in.
messageJSON response. This reference is stolen, so just ast_json_ref if you need to keep a reference to it.

Definition at line 276 of file res_ari.c.

References ast_ari_response::message, ast_ari_response::response_code, and ast_ari_response::response_text.

Referenced by ari_channels_handle_originate_with_id(), ari_channels_handle_snoop_channel(), ast_ari_applications_filter(), ast_ari_applications_get(), ast_ari_applications_list(), ast_ari_applications_subscribe(), ast_ari_applications_unsubscribe(), ast_ari_asterisk_get_global_var(), ast_ari_asterisk_get_info(), ast_ari_asterisk_get_module(), ast_ari_asterisk_list_log_channels(), ast_ari_asterisk_list_modules(), ast_ari_asterisk_ping(), ast_ari_bridges_create(), ast_ari_bridges_create_with_id(), ast_ari_bridges_get(), ast_ari_bridges_list(), ast_ari_channels_create(), ast_ari_channels_get(), ast_ari_channels_get_channel_var(), ast_ari_channels_list(), ast_ari_channels_rtpstatistics(), ast_ari_device_states_get(), ast_ari_device_states_list(), ast_ari_endpoints_get(), ast_ari_endpoints_list(), ast_ari_endpoints_list_by_tech(), ast_ari_get_docs(), ast_ari_mailboxes_get(), ast_ari_mailboxes_list(), ast_ari_playbacks_get(), ast_ari_recordings_copy_stored(), ast_ari_recordings_get_live(), ast_ari_recordings_get_stored(), ast_ari_recordings_get_stored_file(), ast_ari_recordings_list_stored(), ast_ari_sounds_get(), ast_ari_sounds_list(), and return_sorcery_object().

278 {
279  response->message = message;
280  response->response_code = 200;
281  response->response_text = "OK";
282 }
int response_code
Definition: ari.h:98
const char * response_text
Definition: ari.h:102
struct ast_json * message
Definition: ari.h:93

◆ ast_ari_websocket_session_create()

struct ast_ari_websocket_session* ast_ari_websocket_session_create ( struct ast_websocket ws_session,
int(*)(struct ast_json *)  validator 
)

Create an ARI WebSocket session.

If NULL is given for the validator function, no validation will be performed.

Parameters
ws_sessionUnderlying WebSocket session.
validatorFunction to validate outgoing messages.
Returns
New ARI WebSocket session.
NULL on error.

Definition at line 54 of file ari_websockets.c.

References ao2_alloc, ao2_cleanup, ao2_ref, ast_ari_config_get(), ast_log, ast_websocket_set_nonblock(), ast_websocket_set_timeout(), config, errno, LOG_ERROR, LOG_WARNING, NULL, null_validator(), RAII_VAR, session, ast_ari_websocket_session::validator, websocket_session_dtor(), and ast_ari_websocket_session::ws_session.

Referenced by ast_ari_events_event_websocket_ws_established_cb().

56 {
59 
60  if (ws_session == NULL) {
61  return NULL;
62  }
63 
64  if (config == NULL || config->general == NULL) {
65  return NULL;
66  }
67 
68  if (validator == NULL) {
69  validator = null_validator;
70  }
71 
72  if (ast_websocket_set_nonblock(ws_session) != 0) {
74  "ARI web socket failed to set nonblock; closing: %s\n",
75  strerror(errno));
76  return NULL;
77  }
78 
79  if (ast_websocket_set_timeout(ws_session, config->general->write_timeout)) {
80  ast_log(LOG_WARNING, "Failed to set write timeout %d on ARI web socket\n",
81  config->general->write_timeout);
82  }
83 
85  if (!session) {
86  return NULL;
87  }
88 
89  ao2_ref(ws_session, +1);
90  session->ws_session = ws_session;
91  session->validator = validator;
92 
93  ao2_ref(session, +1);
94  return session;
95 }
char * config
Definition: conf2ael.c:66
struct ast_ari_conf * ast_ari_config_get(void)
Get the current ARI configuration.
#define LOG_WARNING
Definition: logger.h:274
All configuration options for ARI.
Definition: internal.h:54
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
static int null_validator(struct ast_json *json)
Validator that always succeeds.
#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
static struct ast_mansession session
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define LOG_ERROR
Definition: logger.h:285
int errno
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
int ast_websocket_set_timeout(struct ast_websocket *session, int timeout)
Set the timeout on a non-blocking WebSocket session.
static void websocket_session_dtor(void *obj)
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int ast_websocket_set_nonblock(struct ast_websocket *session)
Set the socket of a WebSocket session to be non-blocking.

◆ ast_ari_websocket_session_get_remote_addr()

struct ast_sockaddr* ast_ari_websocket_session_get_remote_addr ( struct ast_ari_websocket_session session)

Get the remote address from an ARI WebSocket.

Parameters
sessionSession to write to.
Returns
ast_sockaddr (does not have to be freed)

Definition at line 185 of file ari_websockets.c.

References ast_websocket_remote_address(), and ast_ari_websocket_session::ws_session.

Referenced by ast_ari_websocket_session_write(), and stasis_app_message_handler().

187 {
188  return ast_websocket_remote_address(session->ws_session);
189 }
struct ast_websocket * ws_session
struct ast_sockaddr * ast_websocket_remote_address(struct ast_websocket *session)
Get the remote address for a WebSocket connected session.

◆ ast_ari_websocket_session_id()

const char* ast_ari_websocket_session_id ( const struct ast_ari_websocket_session session)

Get the Session ID for an ARI WebSocket.

Parameters
sessionSession to query.
Returns
Session ID.
NULL on error.

Definition at line 203 of file ari_websockets.c.

References ast_websocket_session_id(), and ast_ari_websocket_session::ws_session.

Referenced by ast_ari_websocket_events_event_websocket_established().

205 {
206  return ast_websocket_session_id(session->ws_session);
207 }
struct ast_websocket * ws_session
const char * ast_websocket_session_id(struct ast_websocket *session)
Get the session ID for a WebSocket session.

◆ ast_ari_websocket_session_read()

struct ast_json* ast_ari_websocket_session_read ( struct ast_ari_websocket_session session)

Read a message from an ARI WebSocket.

Parameters
sessionSession to read from.
Returns
Message received.
NULL if WebSocket could not be read.

Definition at line 97 of file ari_websockets.c.

References ast_debug, ast_json_load_buf(), ast_json_ref(), ast_json_unref(), ast_log, ast_wait_for_input(), ast_websocket_fd(), AST_WEBSOCKET_OPCODE_CLOSE, AST_WEBSOCKET_OPCODE_TEXT, ast_websocket_read(), errno, LOG_WARNING, NULL, RAII_VAR, and ast_ari_websocket_session::ws_session.

Referenced by ast_ari_websocket_events_event_websocket_established().

99 {
101 
102  if (ast_websocket_fd(session->ws_session) < 0) {
103  return NULL;
104  }
105 
106  while (!message) {
107  int res;
108  char *payload;
109  uint64_t payload_len;
110  enum ast_websocket_opcode opcode;
111  int fragmented;
112 
113  res = ast_wait_for_input(
114  ast_websocket_fd(session->ws_session), -1);
115 
116  if (res <= 0) {
117  ast_log(LOG_WARNING, "WebSocket poll error: %s\n",
118  strerror(errno));
119  return NULL;
120  }
121 
122  res = ast_websocket_read(session->ws_session, &payload,
123  &payload_len, &opcode, &fragmented);
124 
125  if (res != 0) {
126  ast_log(LOG_WARNING, "WebSocket read error: %s\n",
127  strerror(errno));
128  return NULL;
129  }
130 
131  switch (opcode) {
133  ast_debug(1, "WebSocket closed\n");
134  return NULL;
136  message = ast_json_load_buf(payload, payload_len, NULL);
137  if (message == NULL) {
139  "WebSocket input failed to parse\n");
140  }
141 
142  break;
143  default:
144  /* Ignore all other message types */
145  break;
146  }
147  }
148 
149  return ast_json_ref(message);
150 }
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
struct ast_json * ast_json_load_buf(const char *buffer, size_t buflen, struct ast_json_error *error)
Parse buffer with known length into a JSON object or array.
Definition: json.c:564
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
#define LOG_WARNING
Definition: logger.h:274
int ast_websocket_fd(struct ast_websocket *session)
Get the file descriptor for a WebSocket session.
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#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
int ast_websocket_read(struct ast_websocket *session, char **payload, uint64_t *payload_len, enum ast_websocket_opcode *opcode, int *fragmented)
Read a WebSocket frame and handle it.
struct ast_websocket * ws_session
int errno
Abstract JSON element (object, array, string, int, ...).
int ast_wait_for_input(int fd, int ms)
Definition: main/utils.c:1519
ast_websocket_opcode
WebSocket operation codes.

◆ ast_ari_websocket_session_write()

int ast_ari_websocket_session_write ( struct ast_ari_websocket_session session,
struct ast_json message 
)

Send a message to an ARI WebSocket.

Parameters
sessionSession to write to.
messageMessage to send.
Returns
0 on success.
Non-zero on error.

Definition at line 158 of file ari_websockets.c.

References ast_ari_json_format(), ast_ari_websocket_session_get_remote_addr(), ast_json_dump_string_format(), ast_json_free(), ast_log, ast_sockaddr_stringify(), ast_websocket_write_string(), LOG_ERROR, LOG_NOTICE, NULL, RAII_VAR, str, VALIDATION_FAILED, ast_ari_websocket_session::validator, and ast_ari_websocket_session::ws_session.

Referenced by event_session_update_websocket(), and stasis_app_message_handler().

160 {
161  RAII_VAR(char *, str, NULL, ast_json_free);
162 
163 #ifdef AST_DEVMODE
164  if (!session->validator(message)) {
165  ast_log(LOG_ERROR, "Outgoing message failed validation\n");
167  }
168 #endif
169 
171 
172  if (str == NULL) {
173  ast_log(LOG_ERROR, "Failed to encode JSON object\n");
174  return -1;
175  }
176 
177  if (ast_websocket_write_string(session->ws_session, str)) {
178  ast_log(LOG_NOTICE, "Problem occurred during websocket write to %s, websocket closed\n",
180  return -1;
181  }
182  return 0;
183 }
enum ast_json_encoding_format ast_ari_json_format(void)
Configured encoding format for JSON output.
Definition: res_ari.c:806
int(* validator)(struct ast_json *)
void ast_json_free(void *p)
Asterisk&#39;s custom JSON allocator. Exposed for use by unit tests.
Definition: json.c:52
struct ast_sockaddr * ast_ari_websocket_session_get_remote_addr(struct ast_ari_websocket_session *session)
Get the remote address from an ARI WebSocket.
const char * str
Definition: app_jack.c:147
#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
#define VALIDATION_FAILED
struct ast_websocket * ws_session
char * ast_json_dump_string_format(struct ast_json *root, enum ast_json_encoding_format format)
Encode a JSON value to a string.
Definition: json.c:463
#define LOG_ERROR
Definition: logger.h:285
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
#define LOG_NOTICE
Definition: logger.h:263
int ast_websocket_write_string(struct ast_websocket *ws, const char *buf)
Construct and transmit a WebSocket frame containing string data.