Asterisk - The Open Source Telephony Project  18.5.0
parking.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Jonathan Rose <[email protected]>
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 /*! \file
20  *
21  * \brief Parking Core
22  *
23  * \author Jonathan Rose <[email protected]>
24  */
25 
26 #include "asterisk.h"
27 
28 #include "asterisk/_private.h"
29 #include "asterisk/astobj2.h"
30 #include "asterisk/pbx.h"
31 #include "asterisk/bridge.h"
32 #include "asterisk/parking.h"
33 #include "asterisk/channel.h"
34 #include "asterisk/_private.h"
35 #include "asterisk/module.h"
36 
37 /*! \brief Message type for parked calls */
39 
40 /*! \brief Topic for parking lots */
41 static struct stasis_topic *parking_topic;
42 
43 /*! \brief The container for the parking provider */
45 
46 static void parking_stasis_cleanup(void)
47 {
49  ao2_cleanup(parking_topic);
50  parking_topic = NULL;
51 }
52 
54 {
56  return -1;
57  }
58 
59  parking_topic = stasis_topic_create("parking:all");
60  if (!parking_topic) {
61  return -1;
62  }
64  return 0;
65 }
66 
68 {
69  return parking_topic;
70 }
71 
72 /*! \brief Destructor for parked_call_payload objects */
73 static void parked_call_payload_destructor(void *obj)
74 {
75  struct ast_parked_call_payload *park_obj = obj;
76 
77  ao2_cleanup(park_obj->parkee);
78  ao2_cleanup(park_obj->retriever);
80 }
81 
83  struct ast_channel_snapshot *parkee_snapshot, const char *parker_dial_string,
84  struct ast_channel_snapshot *retriever_snapshot, const char *parkinglot,
85  unsigned int parkingspace, unsigned long int timeout,
86  unsigned long int duration)
87 {
88  RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
89 
90  payload = ao2_alloc(sizeof(*payload), parked_call_payload_destructor);
91  if (!payload) {
92  return NULL;
93  }
94 
95  if (ast_string_field_init(payload, 32)) {
96  return NULL;
97  }
98 
99  payload->event_type = event_type;
100 
101  ao2_ref(parkee_snapshot, +1);
102  payload->parkee = parkee_snapshot;
103 
104  if (retriever_snapshot) {
105  ao2_ref(retriever_snapshot, +1);
106  payload->retriever = retriever_snapshot;
107  }
108 
109  if (parkinglot) {
110  ast_string_field_set(payload, parkinglot, parkinglot);
111  }
112 
113  if (parker_dial_string) {
114  ast_string_field_set(payload, parker_dial_string, parker_dial_string);
115  }
116 
117  payload->parkingspace = parkingspace;
118  payload->timeout = timeout;
119  payload->duration = duration;
120 
121  /* Bump the ref count by one since RAII_VAR is going to eat one when we leave. */
122  ao2_ref(payload, +1);
123  return payload;
124 }
125 
126 int ast_parking_park_bridge_channel(struct ast_bridge_channel *parkee, const char *parkee_uuid, const char *parker_uuid, const char *app_data)
127 {
130 
131  if (!table || !table->parking_park_bridge_channel) {
132  return -1;
133  }
134 
135  if (table->module) {
136  SCOPED_MODULE_USE(table->module);
137  return table->parking_park_bridge_channel(parkee, parkee_uuid, parker_uuid, app_data);
138  }
139 
140  return table->parking_park_bridge_channel(parkee, parkee_uuid, parker_uuid, app_data);
141 }
142 
144  const char *context, const char *exten, transfer_channel_cb parked_channel_cb,
145  struct transfer_channel_data *parked_channel_data)
146 {
149 
150  if (!table || !table->parking_blind_transfer_park) {
151  return -1;
152  }
153 
154  if (table->module) {
155  SCOPED_MODULE_USE(table->module);
156  return table->parking_blind_transfer_park(parker, context, exten, parked_channel_cb, parked_channel_data);
157  }
158 
159  return table->parking_blind_transfer_park(parker, context, exten, parked_channel_cb, parked_channel_data);
160 }
161 
162 int ast_parking_park_call(struct ast_bridge_channel *parker, char *exten, size_t length)
163 {
166 
167  if (!table || !table->parking_park_call) {
168  return -1;
169  }
170 
171  if (table->module) {
172  SCOPED_MODULE_USE(table->module);
173  return table->parking_park_call(parker, exten, length);
174  }
175 
176  return table->parking_park_call(parker, exten, length);
177 }
178 
179 int ast_parking_is_exten_park(const char *context, const char *exten)
180 {
183 
184  if (!table || !table->parking_is_exten_park) {
185  return -1;
186  }
187 
188  if (table->module) {
189  SCOPED_MODULE_USE(table->module);
190  return table->parking_is_exten_park(context, exten);
191  }
192 
193  return table->parking_is_exten_park(context, exten);
194 }
195 
197 {
200 
201  if (fn_table->module_version != PARKING_MODULE_VERSION) {
202  ast_log(AST_LOG_WARNING, "Parking module provided incorrect parking module "
203  "version: %u (expected: %d)\n", fn_table->module_version, PARKING_MODULE_VERSION);
204  return -1;
205  }
206 
207  if (wrapper) {
208  ast_log(AST_LOG_WARNING, "Parking provider already registered by %s!\n",
209  wrapper->module_name);
210  return -1;
211  }
212 
213  wrapper = ao2_alloc(sizeof(*wrapper), NULL);
214  if (!wrapper) {
215  return -1;
216  }
217  *wrapper = *fn_table;
218 
220  return 0;
221 }
222 
223 int ast_parking_unregister_bridge_features(const char *module_name)
224 {
227 
228  if (!wrapper) {
229  return -1;
230  }
231 
232  if (strcmp(wrapper->module_name, module_name)) {
233  ast_log(AST_LOG_WARNING, "%s has not registered the parking provider\n", module_name);
234  return -1;
235  }
236 
238  return 0;
239 }
240 
242 {
245 
246  return !!table;
247 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
Asterisk main include file. File version handling, generic pbx functions.
static char parkinglot[AST_MAX_CONTEXT]
Definition: chan_mgcp.c:163
Call Parking API.
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1501
int ast_parking_unregister_bridge_features(const char *module_name)
Unregister the current parking provider.
Definition: parking.c:223
struct stasis_message_type * ast_parked_call_type(void)
accessor for the parked call stasis message type
static int timeout
Definition: cdr_mysql.c:86
int ast_parking_register_bridge_features(struct ast_parking_bridge_feature_fn_table *fn_table)
Register a parking provider.
Definition: parking.c:196
#define AST_LOG_WARNING
Definition: logger.h:279
Structure representing a snapshot of channel state.
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1523
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
A parked call message payload.
Definition: parking.h:59
#define NULL
Definition: resample.c:96
STASIS_MESSAGE_TYPE_DEFN(ast_parked_call_type)
Message type for parked calls.
enum ast_parked_call_event_type event_type
Definition: parking.h:62
long unsigned int duration
Definition: parking.h:64
static char * table
Definition: cdr_odbc.c:58
A function table providing parking functionality to the Bridging API Bridging API and other consumers...
Definition: parking.h:127
#define ast_log
Definition: astobj2.c:42
struct ast_channel_snapshot * parkee
Definition: parking.h:60
General Asterisk PBX channel definitions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
#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_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
int ast_parking_park_call(struct ast_bridge_channel *parker, char *exten, size_t length)
Park the bridge and/or callers that this channel is in.
Definition: parking.c:162
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define PARKING_MODULE_VERSION
Definition: parking.h:119
struct stasis_topic * stasis_topic_create(const char *name)
Create a new topic.
Definition: stasis.c:618
Core PBX routines and definitions.
unsigned int module_version
The version of this function table. If the ABI for this table changes, the module version (/ref PARKI...
Definition: parking.h:134
static AO2_GLOBAL_OBJ_STATIC(parking_provider)
The container for the parking provider.
unsigned int parkingspace
Definition: parking.h:65
#define ao2_global_obj_release(holder)
Definition: astobj2.h:865
struct ast_parking_bridge_feature_fn_table parking_provider
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
int ast_parking_blind_transfer_park(struct ast_bridge_channel *parker, const char *context, const char *exten, transfer_channel_cb parked_channel_cb, struct transfer_channel_data *parked_channel_data)
Perform a blind transfer to a parking extension.
Definition: parking.c:143
struct ast_parked_call_payload * ast_parked_call_payload_create(enum ast_parked_call_event_type event_type, struct ast_channel_snapshot *parkee_snapshot, const char *parker_dial_string, struct ast_channel_snapshot *retriever_snapshot, const char *parkinglot, unsigned int parkingspace, unsigned long int timeout, unsigned long int duration)
Constructor for parked_call_payload objects.
Definition: parking.c:82
ast_parked_call_event_type
Defines the type of parked call message being published.
Definition: parking.h:46
int ast_parking_provider_registered(void)
Check whether a parking provider is registered.
Definition: parking.c:241
Prototypes for public functions only of internal interest,.
#define SCOPED_MODULE_USE(module)
Definition: module.h:665
static struct stasis_topic * parking_topic
Topic for parking lots.
Definition: parking.c:41
#define ao2_global_obj_replace_unref(holder, obj)
Definition: astobj2.h:908
int ast_parking_is_exten_park(const char *context, const char *exten)
Determine if the context/exten is a "parking" extension.
Definition: parking.c:179
struct stasis_topic * ast_parking_topic(void)
accessor for the parking stasis topic
Definition: parking.c:67
Structure that contains information regarding a channel in a bridge.
static void parking_stasis_cleanup(void)
Definition: parking.c:46
int ast_parking_stasis_init(void)
initializes the rtp engine arrays
Definition: parking.c:53
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
AO2 object that wraps data for transfer_channel_cb.
Definition: bridge.h:1136
const ast_string_field parker_dial_string
Definition: parking.h:69
void(* transfer_channel_cb)(struct ast_channel *chan, struct transfer_channel_data *user_data, enum ast_transfer_type transfer_type)
Callback function type called during blind transfers.
Definition: bridge.h:1160
int ast_parking_park_bridge_channel(struct ast_bridge_channel *parkee, const char *parkee_uuid, const char *parker_uuid, const char *app_data)
Perform a direct park on a channel in a bridge.
Definition: parking.c:126
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
struct ast_channel_snapshot * retriever
Definition: parking.h:61
Bridging API.
Asterisk module definitions.
static void parked_call_payload_destructor(void *obj)
Destructor for parked_call_payload objects.
Definition: parking.c:73
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514