/*!
 * \internal
 * \since 12.0.0
 * \brief Park a call
 *
 * \param parker The bridge_channel parking the call
 * \param exten Optional. The extension where the call was parked.
 * \param length Optional. If \c exten is specified, the length of the buffer.
 *
 * \note This will determine the context and extension to park the channel based on
 * the configuration of the \ref ast_channel associated with \ref parker. It will then
 * park either the channel or the entire bridge.
 *
 * \retval 0 on success
 * \retval -1 on error
 */
static int parking_park_call(struct ast_bridge_channel *parker, char *exten, size_t length)
{
	RAII_VAR(struct parking_lot *, lot, NULL, ao2_cleanup);
	const char *lot_name = NULL;

	ast_channel_lock(parker->chan);
	lot_name = find_channel_parking_lot_name(parker->chan);
	if (!ast_strlen_zero(lot_name)) {
		lot_name = ast_strdupa(lot_name);
	}
	ast_channel_unlock(parker->chan);

	if (ast_strlen_zero(lot_name)) {
		return -1;
	}

	lot = parking_lot_find_by_name(lot_name);
	if (!lot) {
		ast_log(AST_LOG_WARNING, "Cannot Park %s: lot %s unknown\n",
			ast_channel_name(parker->chan), lot_name);
		return -1;
	}

	if (exten) {
		ast_copy_string(exten, lot->cfg->parkext, length);
	}
	return parking_blind_transfer_park(parker, lot->cfg->parking_con, lot->cfg->parkext, NULL, NULL);
}
Example #2
0
static int manager_parking_status_single_lot(struct mansession *s, const struct message *m, const char *id_text, const char *lot_name)
{
	RAII_VAR(struct parking_lot *, curlot, NULL, ao2_cleanup);
	struct parked_user *curuser;
	struct ao2_iterator iter_users;
	int total = 0;

	curlot = parking_lot_find_by_name(lot_name);

	if (!curlot) {
		astman_send_error(s, m, "Requested parking lot could not be found.");
		return RESULT_SUCCESS;
	}

	astman_send_ack(s, m, "Parked calls will follow");

	iter_users = ao2_iterator_init(curlot->parked_users, 0);
	while ((curuser = ao2_iterator_next(&iter_users))) {
		RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
		RAII_VAR(struct ast_str *, parked_call_string, NULL, ast_free);

		payload = parked_call_payload_from_parked_user(curuser, PARKED_CALL);
		if (!payload) {
			astman_send_error(s, m, "Failed to retrieve parking data about a parked user.");
			return RESULT_FAILURE;
		}

		parked_call_string = manager_build_parked_call_string(payload);
		if (!parked_call_string) {
			astman_send_error(s, m, "Failed to retrieve parkingd ata about a parked user.");
			return RESULT_FAILURE;
		}

		total++;

		astman_append(s, "Event: ParkedCall\r\n"
			"%s" /* The parked call string */
			"%s" /* The action ID */
			"\r\n",
			ast_str_buffer(parked_call_string),
			id_text);

		ao2_ref(curuser, -1);
	}

	ao2_iterator_destroy(&iter_users);

	astman_append(s,
		"Event: ParkedCallsComplete\r\n"
		"Total: %d\r\n"
		"%s"
		"\r\n",
		total, id_text);

	return RESULT_SUCCESS;
}
static void cli_display_parking_lot(int fd, const char *name)
{
	RAII_VAR(struct parking_lot *, lot, NULL, ao2_cleanup);
	lot = parking_lot_find_by_name(name);

	/* If the parking lot couldn't be found with the search, also abort. */
	if (!lot) {
		ast_cli(fd, "Could not find parking lot '%s'\n\n", name);
		return;
	}

	display_parking_lot(lot, fd);

	ast_cli(fd, "Parked Calls\n------------\n");

	if (!ao2_container_count(lot->parked_users)) {
		ast_cli(fd, "  (none)\n");
		ast_cli(fd, "\n\n");
		return;
	}

	ao2_callback(lot->parked_users, OBJ_MULTIPLE | OBJ_NODATA, display_parked_users_cb, &fd);
	ast_cli(fd, "\n");
}