Asterisk - The Open Source Telephony Project  21.4.1
res/res_aeap/message.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2021, Sangoma Technologies Corporation
5  *
6  * Kevin Harwell <kharwell@sangoma.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 #include "asterisk.h"
20 
21 #include "asterisk/astobj2.h"
22 #include "asterisk/utils.h"
23 #include "asterisk/uuid.h"
24 #include "asterisk/res_aeap.h"
26 
28 {
29  ast_assert(type != NULL);
30 
31  return type->serial_type;
32 }
33 
34 static void message_destructor(void *obj)
35 {
36  struct ast_aeap_message *msg = obj;
37 
38  if (msg->type->destruct) {
39  msg->type->destruct(msg);
40  }
41 }
42 
43 static struct ast_aeap_message *message_create(const struct ast_aeap_message_type *type)
44 {
45  struct ast_aeap_message *msg;
46 
47  msg = ao2_t_alloc_options(type->type_size, message_destructor,
49  if (!msg) {
50  ast_log(LOG_ERROR, "AEAP message %s: unable to create\n", type->type_name);
51  return NULL;
52  }
53 
54  msg->type = type;
55 
56  return msg;
57 }
58 
60  const void *params)
61 {
62  struct ast_aeap_message *msg;
63 
64  ast_assert(type != NULL);
65  ast_assert(type->construct1 != NULL);
66 
67  msg = message_create(type);
68  if (!msg) {
69  return NULL;
70  }
71 
72  if (type->construct1(msg, params)) {
73  ast_log(LOG_ERROR, "AEAP message %s: unable to construct1\n", type->type_name);
74  ao2_ref(msg, -1);
75  return NULL;
76  }
77 
78  return msg;
79 }
80 
82  const char *msg_type, const char *name, const char *id, const void *params)
83 {
84  struct ast_aeap_message *msg;
85 
86  ast_assert(type != NULL);
87  ast_assert(type->construct2 != NULL);
88  ast_assert(msg_type != NULL);
89  ast_assert(name != NULL);
90 
91  msg = message_create(type);
92  if (!msg) {
93  return NULL;
94  }
95 
96  if (type->construct2(msg, msg_type, name, id, params)) {
97  ast_log(LOG_ERROR, "AEAP message %s: unable to construct2\n", type->type_name);
98  ao2_ref(msg, -1);
99  return NULL;
100  }
101 
102  return msg;
103 }
104 
106  const char *name, const char *id, const void *params)
107 {
108  struct ast_aeap_message *msg;
109 
110  msg = ast_aeap_message_create2(type, "request", name, id, params);
111  if (!msg) {
112  return NULL;
113  }
114 
115  if (!id && !ast_aeap_message_id_generate(msg)) {
116  ao2_ref(msg, -1);
117  return NULL;
118  }
119 
120  return msg;
121 }
122 
124  const char *name, const char *id, const void *params)
125 {
126  return ast_aeap_message_create2(type, "response", name, id, params);
127 }
128 
130  const char *name, const char *id, const char *error_msg)
131 {
132  struct ast_aeap_message *msg;
133 
134  msg = ast_aeap_message_create_response(type, name, id, NULL);
135  if (!msg) {
136  return NULL;
137  }
138 
139  if (ast_aeap_message_error_msg_set(msg, error_msg)) {
140  ao2_ref(msg, -1);
141  return NULL;
142  }
143 
144  return msg;
145 }
146 
148  const void *buf, intmax_t size)
149 {
150  struct ast_aeap_message *msg;
151 
152  ast_assert(type != NULL);
153  ast_assert(type->deserialize != NULL);
154 
155  msg = ast_aeap_message_create1(type, NULL);
156  if (!msg) {
157  return NULL;
158  }
159 
160  if (type->deserialize(msg, buf, size)) {
161  ao2_ref(msg, -1);
162  return NULL;
163  }
164 
165  return msg;
166 }
167 
169  void **buf, intmax_t *size)
170 {
171  ast_assert(message != NULL);
172  ast_assert(message->type != NULL);
173 
174  return message->type->serialize ? message->type->serialize(message, buf, size) : 0;
175 }
176 
177 const char *ast_aeap_message_id(const struct ast_aeap_message *message)
178 {
179  const char *id = NULL;
180 
181  ast_assert(message != NULL);
182  ast_assert(message->type != NULL);
183 
184  if (message->type->id) {
185  id = message->type->id(message);
186  }
187 
188  return id ? id : "";
189 }
190 
192 {
193  ast_assert(message != NULL);
194  ast_assert(message->type != NULL);
195 
196  return message->type->id_set ? message->type->id_set(message, id) : 0;
197 }
198 
200 {
201  char uuid_str[AST_UUID_STR_LEN];
202 
203  ast_uuid_generate_str(uuid_str, sizeof(uuid_str));
204  if (strlen(uuid_str) != (AST_UUID_STR_LEN - 1)) {
205  ast_log(LOG_ERROR, "AEAP message %s failed to generate UUID for message '%s'",
206  message->type->type_name, ast_aeap_message_name(message));
207  return NULL;
208  }
209 
210  return ast_aeap_message_id_set(message, uuid_str) ? NULL : ast_aeap_message_id(message);
211 }
212 
214 {
215  const char *name = NULL;
216 
217  ast_assert(message != NULL);
218  ast_assert(message->type != NULL);
219 
220  if (message->type->name) {
221  name = message->type->name(message);
222  }
223 
224  return name ? name : "";
225 }
226 
227 int ast_aeap_message_is_named(const struct ast_aeap_message *message, const char *name)
228 {
229  return name ? !strcasecmp(ast_aeap_message_name(message), name) : 0;
230 }
231 
233 {
234  ast_assert(message != NULL);
235  ast_assert(message->type != NULL);
236 
237  return message->type->data ? message->type->data(message) : NULL;
238 }
239 
241 {
242  ast_assert(message != NULL);
243  ast_assert(message->type != NULL);
244 
245  return message->type->is_request ? message->type->is_request(message) : 0;
246 }
247 
249 {
250  ast_assert(message != NULL);
251  ast_assert(message->type != NULL);
252 
253  return message->type->is_response ? message->type->is_response(message) : 0;
254 }
255 
257 {
258  ast_assert(message != NULL);
259  ast_assert(message->type != NULL);
260 
261  return message->type->error_msg ? message->type->error_msg(message) : NULL;
262 }
263 
264 int ast_aeap_message_error_msg_set(struct ast_aeap_message *message, const char *error_msg)
265 {
266  ast_assert(message != NULL);
267  ast_assert(message->type != NULL);
268 
269  return message->type->error_msg_set ? message->type->error_msg_set(message, error_msg) : 0;
270 }
enum AST_AEAP_DATA_TYPE ast_aeap_message_serial_type(const struct ast_aeap_message_type *type)
Retrieve the serial type a message type.
Asterisk External Application Protocol API.
Asterisk main include file. File version handling, generic pbx functions.
Asterisk External Application Protocol Message API.
int(* is_response)(const struct ast_aeap_message *self)
Retrieve whether or not this is a response message.
int ast_aeap_message_is_named(const struct ast_aeap_message *message, const char *name)
Check whether or not a message's name matches the given one.
void * ast_aeap_message_data(struct ast_aeap_message *message)
Retrieve the core message data/body.
int(* construct2)(struct ast_aeap_message *self, const char *msg_type, const char *name, const char *id, const void *params)
Construct/Initialize a message object.
int ast_aeap_message_error_msg_set(struct ast_aeap_message *message, const char *error_msg)
Set an error message.
void *(* data)(struct ast_aeap_message *self)
Retrieve the core message data/body.
Universally unique identifier support.
int(* construct1)(struct ast_aeap_message *self, const void *params)
Construct/Initialize a message object.
#define ao2_t_alloc_options(data_size, destructor_fn, options, debug_msg)
Allocate and initialize an object.
Definition: astobj2.h:402
struct ast_aeap_message * ast_aeap_message_create1(const struct ast_aeap_message_type *type, const void *params)
Create an Asterisk external application message object.
Utility functions.
const char * ast_aeap_message_id(const struct ast_aeap_message *message)
Retrieve a message id.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
const char * ast_aeap_message_name(const struct ast_aeap_message *message)
Retrieve a message name.
int(* is_request)(const struct ast_aeap_message *self)
Retrieve whether or not this is a request message.
int ast_aeap_message_is_request(const struct ast_aeap_message *message)
Retrieve whether or not this is a request message.
int ast_aeap_message_serialize(const struct ast_aeap_message *message, void **buf, intmax_t *size)
Serialize the given message object into a byte/char buffer.
int ast_aeap_message_id_set(struct ast_aeap_message *message, const char *id)
Set a message id.
struct ast_aeap_message * ast_aeap_message_deserialize(const struct ast_aeap_message_type *type, const void *buf, intmax_t size)
Deserialize the given buffer into an Asterisk external application message object.
int(* error_msg_set)(struct ast_aeap_message *self, const char *error_msg)
Set an error message.
struct ast_aeap_message * ast_aeap_message_create_response(const struct ast_aeap_message_type *type, const char *name, const char *id, const void *params)
Create an Asterisk external application response object.
int(* deserialize)(struct ast_aeap_message *self, const void *buf, intmax_t size)
Deserialize the given buffer into a message object.
Asterisk external application base message.
enum AST_AEAP_DATA_TYPE serial_type
void(* destruct)(struct ast_aeap_message *self)
Destruct/Cleanup object resources.
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
Definition: uuid.c:141
AST_AEAP_DATA_TYPE
Supported Asterisk external application data types.
Definition: res_aeap.h:135
Message type virtual method table.
struct ast_aeap_message * ast_aeap_message_create_error(const struct ast_aeap_message_type *type, const char *name, const char *id, const char *error_msg)
Create an Asterisk external application error response object.
const char *(* error_msg)(const struct ast_aeap_message *self)
Retrieve the error message if it has one.
const char *(* id)(const struct ast_aeap_message *self)
Retrieve a message id.
struct ast_aeap_message * ast_aeap_message_create2(const struct ast_aeap_message_type *type, const char *msg_type, const char *name, const char *id, const void *params)
Create an Asterisk external application message object.
const char * ast_aeap_message_id_generate(struct ast_aeap_message *message)
Generate an id, and set it for the message.
struct ast_aeap_message * ast_aeap_message_create_request(const struct ast_aeap_message_type *type, const char *name, const char *id, const void *params)
Create an Asterisk external application request object.
int(* id_set)(struct ast_aeap_message *self, const char *id)
Set a message id.
const struct ast_aeap_message_type * type
const char * ast_aeap_message_error_msg(const struct ast_aeap_message *message)
Retrieve the error message if it has one.
const char *(* name)(const struct ast_aeap_message *self)
Retrieve a message name.
int ast_aeap_message_is_response(const struct ast_aeap_message *message)
Retrieve whether or not this is a response message.
int(* serialize)(const struct ast_aeap_message *self, void **buf, intmax_t *size)
Serialize the message object into byte/char buffer.