Asterisk - The Open Source Telephony Project  GIT-master-a24979a
Data Structures | Macros | Functions | Variables
res_phoneprov.c File Reference

Phone provisioning application for the asterisk internal http server. More...

#include "asterisk.h"
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include "asterisk/channel.h"
#include "asterisk/file.h"
#include "asterisk/paths.h"
#include "asterisk/pbx.h"
#include "asterisk/cli.h"
#include "asterisk/module.h"
#include "asterisk/http.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/strings.h"
#include "asterisk/stringfields.h"
#include "asterisk/options.h"
#include "asterisk/config.h"
#include "asterisk/acl.h"
#include "asterisk/astobj2.h"
#include "asterisk/ast_version.h"
#include "asterisk/phoneprov.h"
Include dependency graph for res_phoneprov.c:

Go to the source code of this file.

Data Structures

struct  extension
 structure to hold extensions More...
 
struct  http_route
 structure to hold http routes (valid URIs, and the files they link to) More...
 
struct  phone_profile
 structure to hold phone profiles read from phoneprov.conf More...
 
struct  phoneprov_file
 structure to hold file data More...
 
struct  phoneprov_provider
 structure to hold config providers More...
 
struct  user
 structure to hold users read from users.conf More...
 

Macros

#define AST_API_MODULE
 
#define FORMATD   "%-20.20s %-20.20s %-40.40s %-30.30s\n"
 
#define FORMATS   "%-20.20s %-40.40s %-30.30s\n"
 
#define MAX_PROFILE_BUCKETS   17
 
#define MAX_PROVIDER_BUCKETS   17
 
#define MAX_ROUTE_BUCKETS   563
 
#define MAX_USER_BUCKETS   563
 
#define SIMPLE_CMP_FN(fname, stype, field)
 Creates a compare function for a structure string field. More...
 
#define SIMPLE_HASH_FN(fname, stype, field)
 Creates a hash function for a structure string field. More...
 
#define SIPUSERS_PROVIDER_NAME   "sipusers"
 
#define VAR_BUF_SIZE   4096
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static int add_user_extension (struct user *user, struct extension *exten)
 Add an extension to a user ordered by index/linenumber. More...
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
int ast_phoneprov_add_extension (char *provider_name, struct varshead *vars)
 Adds an extension. More...
 
void ast_phoneprov_delete_extension (char *provider_name, char *macaddress)
 Deletes an extension. More...
 
void ast_phoneprov_delete_extensions (char *provider_name)
 Deletes all extensions for this provider. More...
 
int ast_phoneprov_provider_register (char *provider_name, ast_phoneprov_load_users_cb load_users)
 Registers a config provider to phoneprov. More...
 
void ast_phoneprov_provider_unregister (char *provider_name)
 Unegisters a config provider from phoneprov and frees its resources. More...
 
const char * ast_phoneprov_std_variable_lookup (enum ast_phoneprov_std_variables var)
 Returns the string respresentation of a phoneprov standard variable. More...
 
static struct extensionbuild_extension (const char *name, struct varshead *vars)
 
static void build_profile (const char *name, struct ast_variable *v)
 Build a phone profile and add it to the list of phone profiles. More...
 
static void build_route (struct phoneprov_file *pp_file, struct phone_profile *profile, struct user *user, char *uri)
 Build a route structure and add it to the list of available http routes. More...
 
static struct userbuild_user (const char *mac, struct phone_profile *profile, char *provider_name)
 Build and return a user structure based on gathered config data. More...
 
static int build_user_routes (struct user *user)
 Add an http route for dynamic files attached to the profile of the user. More...
 
static struct extensiondelete_extension (struct extension *exten)
 
static void delete_file (struct phoneprov_file *file)
 
static void delete_profiles (void)
 Delete all phone profiles, freeing their memory. More...
 
static void delete_providers (void)
 Delete all providers. More...
 
static void delete_routes (void)
 Delete all http routes, freeing their memory. More...
 
static void delete_users (void)
 Delete all users. More...
 
static int extension_delete_cb (void *obj, void *arg, void *data, int flags)
 
static int extensions_delete_cb (void *obj, void *arg, int flags)
 
static struct phone_profilefind_profile (const char *name)
 Return a phone profile looked up by name. More...
 
static struct phoneprov_providerfind_provider (char *name)
 
static struct userfind_user (const char *macaddress)
 Return a user looked up by name. More...
 
static struct varsheadget_defaults (void)
 
static char * handle_show_routes (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command to list static and dynamic routes. More...
 
static int load_common (void)
 
static int load_file (const char *filename, char **ret)
 Read a TEXT file into a string and return the length. More...
 
static int load_module (void)
 Load the module. More...
 
static int load_users (void)
 
static int lookup_iface (const char *iface, struct in_addr *address)
 
static int phoneprov_callback (struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_vars, struct ast_variable *headers)
 Callback that is executed everytime an http request is received by this module. More...
 
static int pp_each_extension_helper (struct ast_channel *chan, const char *cmd, char *data, char *buf, struct ast_str **bufstr, int len)
 A dialplan function that can be used to output a template for each extension attached to a user. More...
 
static int pp_each_extension_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 
static int pp_each_extension_read2 (struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
 
static int pp_each_user_helper (struct ast_channel *chan, char *data, char *buf, struct ast_str **bufstr, int len)
 A dialplan function that can be used to print a string for each phoneprov user. More...
 
static int pp_each_user_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 
static int pp_each_user_read2 (struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
 
static void profile_destructor (void *obj)
 
static void provider_destructor (void *obj)
 
static int reload (void)
 
static void route_destructor (void *obj)
 
static int route_list_cb (void *obj, void *arg, void *data, int flags)
 
static int routes_delete_cb (void *obj, void *arg, int flags)
 
static void set_timezone_variables (struct varshead *headp, const char *zone)
 Set all timezone-related variables based on a zone (i.e. America/New_York) More...
 
static int unload_module (void)
 
static struct phone_profileunref_profile (struct phone_profile *prof)
 
static struct http_routeunref_route (struct http_route *route)
 
static struct userunref_user (struct user *user)
 
static void user_destructor (void *obj)
 Free all memory associated with a user. More...
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "HTTP Phone Provisioning" , .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_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DEPEND, .requires = "http", }
 
static struct in_addr __ourip = { .s_addr = 0x00000000, }
 for use in lookup_iface More...
 
static const struct ast_module_infoast_module_info = &__mod_info
 
struct ao2_containerhttp_routes
 
static struct ast_http_uri phoneprovuri
 
static struct ast_cli_entry pp_cli []
 
static struct ast_custom_function pp_each_extension_function
 
static struct ast_custom_function pp_each_user_function
 
static const char * pp_general_lookup []
 
static const char * pp_user_lookup []
 
struct ao2_containerprofiles
 
struct ao2_containerproviders
 
struct ao2_containerusers
 
static const char * variable_lookup []
 

Detailed Description

Phone provisioning application for the asterisk internal http server.

Author
Matthew Brooks mbroo.nosp@m.ks@d.nosp@m.igium.nosp@m..com
Terry Wilson twils.nosp@m.on@d.nosp@m.igium.nosp@m..com
George Joseph georg.nosp@m.e.jo.nosp@m.seph@.nosp@m.fair.nosp@m.view5.nosp@m..com

Definition in file res_phoneprov.c.

Macro Definition Documentation

◆ AST_API_MODULE

#define AST_API_MODULE

Definition at line 45 of file res_phoneprov.c.

◆ FORMATD

#define FORMATD   "%-20.20s %-20.20s %-40.40s %-30.30s\n"

Definition at line 1140 of file res_phoneprov.c.

◆ FORMATS

#define FORMATS   "%-20.20s %-40.40s %-30.30s\n"

Definition at line 1139 of file res_phoneprov.c.

◆ MAX_PROFILE_BUCKETS

#define MAX_PROFILE_BUCKETS   17

Definition at line 81 of file res_phoneprov.c.

◆ MAX_PROVIDER_BUCKETS

#define MAX_PROVIDER_BUCKETS   17

Definition at line 80 of file res_phoneprov.c.

◆ MAX_ROUTE_BUCKETS

#define MAX_ROUTE_BUCKETS   563

Definition at line 82 of file res_phoneprov.c.

◆ MAX_USER_BUCKETS

#define MAX_USER_BUCKETS   563

Definition at line 83 of file res_phoneprov.c.

◆ SIMPLE_CMP_FN

#define SIMPLE_CMP_FN (   fname,
  stype,
  field 
)

Creates a compare function for a structure string field.

Parameters
fnameThe name to use for the function
stypeThe structure type
fieldThe field in the structure to compare

SIMPLE_CMP_FN(mystruct, myfield) will produce a function named mystruct_cmp_fn which compares mystruct->myfield.

Definition at line 157 of file res_phoneprov.c.

◆ SIMPLE_HASH_FN

#define SIMPLE_HASH_FN (   fname,
  stype,
  field 
)

Creates a hash function for a structure string field.

Parameters
fnameThe name to use for the function
stypeThe structure type
fieldThe field in the structure to hash

SIMPLE_HASH_FN(mystruct, myfield) will produce a function named mystruct_hash_fn which hashes mystruct->myfield.

Definition at line 128 of file res_phoneprov.c.

◆ SIPUSERS_PROVIDER_NAME

#define SIPUSERS_PROVIDER_NAME   "sipusers"

Definition at line 338 of file res_phoneprov.c.

◆ VAR_BUF_SIZE

#define VAR_BUF_SIZE   4096

Definition at line 86 of file res_phoneprov.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1509 of file res_phoneprov.c.

1514 {

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1509 of file res_phoneprov.c.

1514 {

◆ add_user_extension()

static int add_user_extension ( struct user user,
struct extension exten 
)
static

Add an extension to a user ordered by index/linenumber.

Definition at line 806 of file res_phoneprov.c.

807 {
808  struct ast_var_t *pvar, *var2;
809  struct ast_str *str = ast_str_create(16);
810 
811  if (!str) {
812  return -1;
813  }
814 
815  /* Append profile variables here, and substitute variables on profile
816  * setvars, so that we can use user specific variables in them */
818  if (ast_var_find(exten->headp, pvar->name)) {
819  continue;
820  }
821 
823  if ((var2 = ast_var_assign(pvar->name, ast_str_buffer(str)))) {
824  AST_VAR_LIST_INSERT_TAIL(exten->headp, var2);
825  }
826  }
827  ast_free(str);
828 
829  if (AST_LIST_EMPTY(&user->extensions)) {
831  } else {
832  struct extension *exten_iter;
833 
835  if (exten->index < exten_iter->index) {
837  } else if (exten->index == exten_iter->index) {
838  ast_log(LOG_WARNING, "Duplicate linenumber=%d for %s\n", exten->index, user->macaddress);
839  return -1;
840  } else if (!AST_LIST_NEXT(exten_iter, entry)) {
842  }
843  }
845  }
846 
847  return 0;
848 }
const char * str
Definition: app_jack.c:147
#define ast_free(a)
Definition: astmm.h:180
#define ast_log
Definition: astobj2.c:42
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:122
char * ast_var_find(const struct varshead *head, const char *name)
Definition: chanvars.c:85
static void AST_VAR_LIST_INSERT_TAIL(struct varshead *head, struct ast_var_t *var)
Definition: chanvars.h:51
#define AST_VAR_LIST_TRAVERSE(head, var)
Definition: chanvars.h:49
#define ast_var_assign(name, value)
Definition: chanvars.h:40
#define LOG_WARNING
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:450
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_INSERT_BEFORE_CURRENT(elm, field)
Inserts a list entry before the current entry during a traversal.
Definition: linkedlists.h:599
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:711
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
void ast_str_substitute_variables_varshead(struct ast_str **buf, ssize_t maxlen, struct varshead *headp, const char *templ)
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:739
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:640
Support for dynamic strings.
Definition: strings.h:604
char name[0]
Definition: chanvars.h:31
char * value
Definition: chanvars.h:30
Definition: search.h:40
structure to hold extensions
struct varshead * headp
structure to hold users read from users.conf
const ast_string_field macaddress
struct phone_profile * profile
struct user::@478 extensions

References ast_free, AST_LIST_EMPTY, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_HEAD, AST_LIST_INSERT_TAIL, AST_LIST_NEXT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log, ast_str_buffer(), ast_str_create, ast_str_substitute_variables_varshead(), ast_var_assign, ast_var_find(), AST_VAR_LIST_INSERT_TAIL(), AST_VAR_LIST_TRAVERSE, exten, user::extensions, phone_profile::headp, extension::index, LOG_WARNING, user::macaddress, ast_var_t::name, user::profile, str, and ast_var_t::value.

Referenced by ast_phoneprov_add_extension().

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 1509 of file res_phoneprov.c.

1514 {

◆ ast_phoneprov_add_extension()

int ast_phoneprov_add_extension ( char *  provider_name,
struct varshead vars 
)

Adds an extension.

Parameters
provider_nameThe name of the provider
varsAn ast_vat_t linked list of the extension's variables. The list is automatically cloned and it must contain at least MACADDRESS and USERNAME entries.
Return values
0if successful
non-zeroif failure

Definition at line 1622 of file res_phoneprov.c.

1623 {
1625  RAII_VAR(struct user *, user, NULL, ao2_cleanup);
1626  RAII_VAR(struct phone_profile *, profile, NULL, ao2_cleanup);
1627  struct extension *exten;
1628  char *profile_name;
1629  char *mac;
1630  char *username;
1631 
1632  if (ast_strlen_zero(provider_name)) {
1633  ast_log(LOG_ERROR, "Provider name can't be empty.\n");
1634  return -1;
1635  }
1636  if (!vars) {
1637  ast_log(LOG_ERROR, "Variable list can't be empty.\n");
1638  return -1;
1639  }
1640 
1642  if (!username) {
1643  ast_log(LOG_ERROR, "Extension name can't be empty.\n");
1644  return -1;
1645  }
1646 
1648  if (!mac) {
1649  ast_log(LOG_ERROR, "MAC Address can't be empty.\n");
1650  return -1;
1651  }
1652 
1653  provider = find_provider(provider_name);
1654  if (!provider) {
1655  ast_log(LOG_ERROR, "Provider '%s' wasn't found in the registry.\n", provider_name);
1656  return -1;
1657  }
1658 
1659  profile_name = ast_var_find(vars,
1661  if (!profile_name) {
1662  ast_log(LOG_ERROR, "No profile could be found for user '%s' - skipping.\n", username);
1663  return -1;
1664  }
1665  if (!(profile = find_profile(profile_name))) {
1666  ast_log(LOG_ERROR, "Could not look up profile '%s' - skipping.\n", profile_name);
1667  return -1;
1668  }
1669 
1670  if (!(user = find_user(mac))) {
1671 
1672  if (!(user = build_user(mac, profile, provider_name))) {
1673  ast_log(LOG_ERROR, "Could not create user for '%s' - skipping\n", mac);
1674  return -1;
1675  }
1676 
1677  if (!(exten = build_extension(username, vars))) {
1678  ast_log(LOG_ERROR, "Could not create extension for '%s' - skipping\n", user->macaddress);
1679  return -1;
1680  }
1681 
1682  if (add_user_extension(user, exten)) {
1683  ast_log(LOG_WARNING, "Could not add extension '%s' to user '%s'\n", exten->name, user->macaddress);
1685  return -1;
1686  }
1687 
1688  if (build_user_routes(user)) {
1689  ast_log(LOG_WARNING, "Could not create http routes for '%s' - skipping\n", user->macaddress);
1690  return -1;
1691  }
1692  ao2_link(users, user);
1693 
1694  } else {
1695  if (strcmp(provider_name, user->provider_name)) {
1696  ast_log(LOG_ERROR, "MAC address '%s' was already added by provider '%s' - skipping\n", user->macaddress, user->provider_name);
1697  return -1;
1698  }
1699 
1700  if (!(exten = build_extension(username, vars))) {
1701  ast_log(LOG_ERROR, "Could not create extension for '%s' - skipping\n", user->macaddress);
1702  return -1;
1703  }
1704 
1705  if (add_user_extension(user, exten)) {
1706  ast_log(LOG_WARNING, "Could not add extension '%s' to user '%s'\n", exten->name, user->macaddress);
1708  return -1;
1709  }
1710  }
1711 
1712  return 0;
1713 }
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
static struct prometheus_metrics_provider provider
Definition: bridges.c:178
#define LOG_ERROR
@ AST_PHONEPROV_STD_MAC
Definition: phoneprov.h:30
@ AST_PHONEPROV_STD_USERNAME
Definition: phoneprov.h:32
@ AST_PHONEPROV_STD_PROFILE
Definition: phoneprov.h:31
static struct phone_profile * find_profile(const char *name)
Return a phone profile looked up by name.
static struct extension * delete_extension(struct extension *exten)
static int build_user_routes(struct user *user)
Add an http route for dynamic files attached to the profile of the user.
static struct user * build_user(const char *mac, struct phone_profile *profile, char *provider_name)
Build and return a user structure based on gathered config data.
static struct phoneprov_provider * find_provider(char *name)
static const char * variable_lookup[]
static struct user * find_user(const char *macaddress)
Return a user looked up by name.
static struct extension * build_extension(const char *name, struct varshead *vars)
static int add_user_extension(struct user *user, struct extension *exten)
Add an extension to a user ordered by index/linenumber.
#define NULL
Definition: resample.c:96
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
structure to hold phone profiles read from phoneprov.conf
structure to hold config providers
const ast_string_field provider_name
list of users found in the config file
#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:936

References add_user_extension(), ao2_cleanup, ao2_link, ast_log, AST_PHONEPROV_STD_MAC, AST_PHONEPROV_STD_PROFILE, AST_PHONEPROV_STD_USERNAME, ast_strlen_zero(), ast_var_find(), build_extension(), build_user(), build_user_routes(), delete_extension(), exten, find_profile(), find_provider(), find_user(), LOG_ERROR, LOG_WARNING, user::macaddress, NULL, user::profile, provider, user::provider_name, RAII_VAR, and variable_lookup.

Referenced by load_users(), and users_apply_handler().

◆ ast_phoneprov_delete_extension()

void ast_phoneprov_delete_extension ( char *  provider_name,
char *  macaddress 
)

Deletes an extension.

Parameters
provider_nameThe name of the provider
macaddressThe mac address of the extension

Definition at line 1593 of file res_phoneprov.c.

1594 {
1595  if (!users) {
1596  return;
1597  }
1598 
1600  extension_delete_cb, macaddress, provider_name);
1601 }
#define ao2_callback_data(container, flags, cb_fn, arg, data)
Definition: astobj2.h:1723
@ OBJ_NODATA
Definition: astobj2.h:1044
@ OBJ_MULTIPLE
Definition: astobj2.h:1049
@ OBJ_UNLINK
Definition: astobj2.h:1039
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
static int extension_delete_cb(void *obj, void *arg, void *data, int flags)

References ao2_callback_data, extension_delete_cb(), user::macaddress, OBJ_MULTIPLE, OBJ_NODATA, OBJ_SEARCH_KEY, OBJ_UNLINK, and user::provider_name.

Referenced by phoneprov_destroy().

◆ ast_phoneprov_delete_extensions()

void ast_phoneprov_delete_extensions ( char *  provider_name)

Deletes all extensions for this provider.

Parameters
provider_nameThe name of the provider

Definition at line 1603 of file res_phoneprov.c.

1604 {
1605  if (!users) {
1606  return;
1607  }
1608 
1610 }
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
static int extensions_delete_cb(void *obj, void *arg, int flags)

References ao2_callback, extensions_delete_cb(), OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, and user::provider_name.

Referenced by ast_phoneprov_provider_unregister().

◆ ast_phoneprov_provider_register()

int ast_phoneprov_provider_register ( char *  provider_name,
ast_phoneprov_load_users_cb  load_users 
)

Registers a config provider to phoneprov.

Parameters
provider_nameThe name of the provider
load_usersCallback that gathers user variables then loads them by calling ast_phoneprov_add_extension once for each extension.
Return values
0if successful
non-zeroif failure

Definition at line 1522 of file res_phoneprov.c.

1524 {
1525  struct phoneprov_provider *provider;
1526 
1528  ast_log(LOG_ERROR, "Provider name can't be empty.\n");
1529  return -1;
1530  }
1531 
1532  if (!providers) {
1533  ast_log(LOG_WARNING, "Provider '%s' cannot be registered: res_phoneprov not loaded.\n", provider_name);
1534  return -1;
1535  }
1536 
1538  if (provider) {
1539  ast_log(LOG_ERROR, "There is already a provider registered named '%s'.\n", provider_name);
1540  ao2_ref(provider, -1);
1541  return -1;
1542  }
1543 
1545  if (!provider) {
1546  ast_log(LOG_ERROR, "Unable to allocate sufficient memory for provider '%s'.\n", provider_name);
1547  return -1;
1548  }
1549 
1550  if (ast_string_field_init(provider, 32)) {
1551  ao2_ref(provider, -1);
1552  ast_log(LOG_ERROR, "Unable to allocate sufficient memory for provider '%s' stringfields.\n", provider_name);
1553  return -1;
1554  }
1555 
1557  provider->load_users = load_users;
1558 
1560  ao2_ref(provider, -1);
1561 
1562  if (provider->load_users()) {
1563  ast_log(LOG_ERROR, "Unable to load provider '%s' users. Register aborted.\n", provider_name);
1565  return -1;
1566  }
1567 
1568  return 0;
1569 }
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static void provider_destructor(void *obj)
void ast_phoneprov_provider_unregister(char *provider_name)
Unegisters a config provider from phoneprov and frees its resources.
static int load_users(void)
struct ao2_container * providers
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
const ast_string_field provider_name

References ao2_alloc, ao2_link, ao2_ref, ast_log, ast_phoneprov_provider_unregister(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), find_provider(), load_users(), LOG_ERROR, LOG_WARNING, provider, provider_destructor(), phoneprov_provider::provider_name, and providers.

Referenced by load_module().

◆ ast_phoneprov_provider_unregister()

void ast_phoneprov_provider_unregister ( char *  provider_name)

Unegisters a config provider from phoneprov and frees its resources.

Parameters
provider_nameThe name of the provider

Definition at line 1612 of file res_phoneprov.c.

1613 {
1614  if (!providers) {
1615  return;
1616  }
1617 
1618  ast_phoneprov_delete_extensions(provider_name);
1619  ao2_find(providers, provider_name, OBJ_SEARCH_KEY | OBJ_NODATA | OBJ_UNLINK);
1620 }
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
void ast_phoneprov_delete_extensions(char *provider_name)
Deletes all extensions for this provider.

References ao2_find, ast_phoneprov_delete_extensions(), OBJ_NODATA, OBJ_SEARCH_KEY, OBJ_UNLINK, user::provider_name, and providers.

Referenced by ast_phoneprov_provider_register(), and unload_module().

◆ ast_phoneprov_std_variable_lookup()

const char* ast_phoneprov_std_variable_lookup ( enum ast_phoneprov_std_variables  var)

Returns the string respresentation of a phoneprov standard variable.

Parameters
varOne of enum ast_phoneprov_std_variables
Returns
The string representation or NULL if not found.

Definition at line 1513 of file res_phoneprov.c.

1514 {
1516  return NULL;
1517  }
1518 
1519  return variable_lookup[var];
1520 }
#define var
Definition: ast_expr2f.c:614
@ AST_PHONEPROV_STD_VAR_LIST_LENGTH
Definition: phoneprov.h:53

References AST_PHONEPROV_STD_VAR_LIST_LENGTH, NULL, var, and variable_lookup.

Referenced by load_endpoint(), and users_apply_handler().

◆ build_extension()

static struct extension* build_extension ( const char *  name,
struct varshead vars 
)
static

Definition at line 689 of file res_phoneprov.c.

690 {
691  struct extension *exten;
692  const char *tmp;
693 
694  if (!(exten = ast_calloc_with_stringfields(1, struct extension, 32))) {
695  return NULL;
696  }
697 
699 
700  exten->headp = ast_var_list_clone(vars);
701  if (!exten->headp) {
702  ast_log(LOG_ERROR, "Unable to clone variables for extension '%s'\n", name);
704  return NULL;
705  }
706 
708  if (!tmp) {
711  exten->index = 1;
712  } else {
713  sscanf(tmp, "%d", &exten->index);
714  }
715 
719  }
720 
723 
724  return exten;
725 }
static int tmp()
Definition: bt_open.c:389
struct varshead * ast_var_list_clone(struct varshead *head)
Definition: chanvars.c:124
static const char name[]
Definition: format_mp3.c:68
@ AST_PHONEPROV_STD_LINENUMBER
Definition: phoneprov.h:38
@ AST_PHONEPROV_STD_TIMEZONE
Definition: phoneprov.h:37
@ AST_PHONEPROV_STD_LINEKEYS
Definition: phoneprov.h:39
static void set_timezone_variables(struct varshead *headp, const char *zone)
Set all timezone-related variables based on a zone (i.e. America/New_York)
#define ast_calloc_with_stringfields(n, type, size)
Allocate a structure with embedded stringfields in a single allocation.
Definition: stringfields.h:432

References ast_calloc_with_stringfields, ast_log, AST_PHONEPROV_STD_LINEKEYS, AST_PHONEPROV_STD_LINENUMBER, AST_PHONEPROV_STD_TIMEZONE, ast_string_field_set, ast_var_assign, ast_var_find(), ast_var_list_clone(), AST_VAR_LIST_INSERT_TAIL(), delete_extension(), exten, LOG_ERROR, name, NULL, set_timezone_variables(), tmp(), and variable_lookup.

Referenced by ast_phoneprov_add_extension().

◆ build_profile()

static void build_profile ( const char *  name,
struct ast_variable v 
)
static

Build a phone profile and add it to the list of phone profiles.

Parameters
namethe name of the profile
vast_variable from parsing phoneprov.conf

Definition at line 585 of file res_phoneprov.c.

586 {
587  struct phone_profile *profile;
588 
589  if (!(profile = ao2_alloc(sizeof(*profile), profile_destructor))) {
590  return;
591  }
592 
593  if (ast_string_field_init(profile, 32)) {
594  profile = unref_profile(profile);
595  return;
596  }
597 
598  if (!(profile->headp = ast_var_list_create())) {
599  profile = unref_profile(profile);
600  return;
601  }
602 
605 
606  ast_string_field_set(profile, name, name);
607  for (; v; v = v->next) {
608  if (!strcasecmp(v->name, "mime_type")) {
610  } else if (!strcasecmp(v->name, "setvar")) {
611  char value_copy[strlen(v->value) + 1];
612 
614  AST_APP_ARG(varname);
615  AST_APP_ARG(varval);
616  );
617 
618  strcpy(value_copy, v->value); /* safe */
619  AST_NONSTANDARD_APP_ARGS(args, value_copy, '=');
620  do {
621  if (ast_strlen_zero(args.varname) || ast_strlen_zero(args.varval))
622  break;
623  args.varname = ast_strip(args.varname);
624  args.varval = ast_strip(args.varval);
625  if (ast_strlen_zero(args.varname) || ast_strlen_zero(args.varval))
626  break;
627  AST_VAR_LIST_INSERT_TAIL(profile->headp, ast_var_assign(args.varname, args.varval));
628  } while (0);
629  } else if (!strcasecmp(v->name, "staticdir")) {
630  ast_string_field_set(profile, staticdir, v->value);
631  } else {
632  struct phoneprov_file *pp_file;
633  char *file_extension;
634  char value_copy[strlen(v->value) + 1];
635 
637  AST_APP_ARG(filename);
638  AST_APP_ARG(mimetype);
639  );
640 
641  if (!(pp_file = ast_calloc_with_stringfields(1, struct phoneprov_file, 32))) {
642  profile = unref_profile(profile);
643  return;
644  }
645 
646  if ((file_extension = strrchr(pp_file->format, '.')))
647  file_extension++;
648 
649  strcpy(value_copy, v->value); /* safe */
650  AST_STANDARD_APP_ARGS(args, value_copy);
651 
652  /* Mime type order of preference
653  * 1) Specific mime-type defined for file in profile
654  * 2) Mime determined by extension
655  * 3) Default mime type specified in profile
656  * 4) text/plain
657  */
658  ast_string_field_set(pp_file, mime_type, S_OR(args.mimetype,
659  (S_OR(S_OR(ast_http_ftype2mtype(file_extension), profile->default_mime_type), "text/plain"))));
660 
661  if (!strcasecmp(v->name, "static_file")) {
662  ast_string_field_set(pp_file, format, args.filename);
663  ast_string_field_build(pp_file, template, "%s%s", profile->staticdir, args.filename);
664  AST_LIST_INSERT_TAIL(&profile->static_files, pp_file, entry);
665  /* Add a route for the static files, as their filenames won't change per-user */
666  build_route(pp_file, profile, NULL, NULL);
667  } else {
668  ast_string_field_set(pp_file, format, v->name);
669  ast_string_field_set(pp_file, template, args.filename);
670  AST_LIST_INSERT_TAIL(&profile->dynamic_files, pp_file, entry);
671  }
672  }
673  }
674 
675  ao2_link(profiles, profile);
676 
677  profile = unref_profile(profile);
678 }
static snd_pcm_format_t format
Definition: chan_alsa.c:106
struct varshead * ast_var_list_create(void)
Definition: chanvars.c:97
const char * ast_http_ftype2mtype(const char *ftype) attribute_pure
Return mime type based on extension.
Definition: http.c:206
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
static void profile_destructor(void *obj)
static struct phone_profile * unref_profile(struct phone_profile *prof)
struct ao2_container * profiles
static void build_route(struct phoneprov_file *pp_file, struct phone_profile *profile, struct user *user, char *uri)
Build a route structure and add it to the list of available http routes.
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:555
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
struct ast_variable * next
struct phone_profile::@476 static_files
const ast_string_field staticdir
const ast_string_field default_mime_type
struct phone_profile::@477 dynamic_files
structure to hold file data
const ast_string_field mime_type
const ast_string_field format
const char * args

References ao2_alloc, ao2_link, args, AST_APP_ARG, ast_calloc_with_stringfields, AST_DECLARE_APP_ARGS, ast_http_ftype2mtype(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_TAIL, AST_NONSTANDARD_APP_ARGS, AST_STANDARD_APP_ARGS, ast_string_field_build, ast_string_field_init, ast_string_field_set, ast_strip(), ast_strlen_zero(), ast_var_assign, ast_var_list_create(), AST_VAR_LIST_INSERT_TAIL(), build_route(), phone_profile::default_mime_type, phone_profile::dynamic_files, format, phoneprov_file::format, phone_profile::headp, phoneprov_file::mime_type, name, ast_variable::name, ast_variable::next, NULL, profile_destructor(), profiles, S_OR, phone_profile::static_files, phone_profile::staticdir, unref_profile(), and ast_variable::value.

Referenced by load_common().

◆ build_route()

static void build_route ( struct phoneprov_file pp_file,
struct phone_profile profile,
struct user user,
char *  uri 
)
static

Build a route structure and add it to the list of available http routes.

Parameters
pp_fileFile to link to the route
profile
userUser to link to the route (NULL means static route)
uriURI of the route

Definition at line 512 of file res_phoneprov.c.

513 {
514  struct http_route *route;
515 
516  if (!(route = ao2_alloc(sizeof(*route), route_destructor))) {
517  return;
518  }
519 
520  if (ast_string_field_init(route, 32)) {
521  ast_log(LOG_ERROR, "Couldn't create string fields for %s\n", pp_file->format);
522  route = unref_route(route);
523  return;
524  }
525 
526  ast_string_field_set(route, uri, S_OR(uri, pp_file->format));
527  route->user = user;
528  route->file = pp_file;
529  route->profile = profile;
530 
531  ao2_link(http_routes, route);
532 
533  route = unref_route(route);
534 }
static char user[512]
static struct http_route * unref_route(struct http_route *route)
struct ao2_container * http_routes
static void route_destructor(void *obj)
structure to hold http routes (valid URIs, and the files they link to)
const ast_string_field uri
struct phone_profile * profile
struct phoneprov_file * file
struct user * user

References ao2_alloc, ao2_link, ast_log, ast_string_field_init, ast_string_field_set, http_route::file, phoneprov_file::format, http_routes, LOG_ERROR, http_route::profile, route_destructor(), S_OR, unref_route(), http_route::uri, user, and http_route::user.

Referenced by build_profile(), and build_user_routes().

◆ build_user()

static struct user* build_user ( const char *  mac,
struct phone_profile profile,
char *  provider_name 
)
static

Build and return a user structure based on gathered config data.

Definition at line 784 of file res_phoneprov.c.

785 {
786  struct user *user;
787 
788  if (!(user = ao2_alloc(sizeof(*user), user_destructor))) {
789  return NULL;
790  }
791 
792  if (ast_string_field_init(user, 64)) {
793  user = unref_user(user);
794  return NULL;
795  }
796 
799  user->profile = profile;
800  ao2_ref(profile, 1);
801 
802  return user;
803 }
static struct user * unref_user(struct user *user)
static void user_destructor(void *obj)
Free all memory associated with a user.

References ao2_alloc, ao2_ref, ast_string_field_init, ast_string_field_set, user::macaddress, NULL, user::profile, user::provider_name, unref_user(), user, and user_destructor().

Referenced by ast_phoneprov_add_extension().

◆ build_user_routes()

static int build_user_routes ( struct user user)
static

Add an http route for dynamic files attached to the profile of the user.

Definition at line 851 of file res_phoneprov.c.

852 {
853  struct phoneprov_file *pp_file;
854  struct ast_str *str;
855 
856  if (!(str = ast_str_create(16))) {
857  return -1;
858  }
859 
863  }
864 
865  ast_free(str);
866  return 0;
867 }
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:421

References ast_free, AST_LIST_FIRST, AST_LIST_TRAVERSE, ast_str_buffer(), ast_str_create, ast_str_substitute_variables_varshead(), build_route(), phone_profile::dynamic_files, user::extensions, phoneprov_file::format, user::profile, and str.

Referenced by ast_phoneprov_add_extension().

◆ delete_extension()

static struct extension* delete_extension ( struct extension exten)
static

Definition at line 680 of file res_phoneprov.c.

681 {
682  ast_var_list_destroy(exten->headp);
684  ast_free(exten);
685 
686  return NULL;
687 }
void ast_var_list_destroy(struct varshead *head)
Definition: chanvars.c:109
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374

References ast_free, ast_string_field_free_memory, ast_var_list_destroy(), exten, and NULL.

Referenced by ast_phoneprov_add_extension(), build_extension(), and user_destructor().

◆ delete_file()

static void delete_file ( struct phoneprov_file file)
static

Definition at line 392 of file res_phoneprov.c.

References ast_free, ast_string_field_free_memory, and make_ari_stubs::file.

Referenced by profile_destructor().

◆ delete_profiles()

static void delete_profiles ( void  )
static

Delete all phone profiles, freeing their memory.

Definition at line 572 of file res_phoneprov.c.

573 {
574  if (!profiles) {
575  return;
576  }
577 
579 }

References ao2_callback, NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, and profiles.

Referenced by unload_module().

◆ delete_providers()

static void delete_providers ( void  )
static

Delete all providers.

Definition at line 377 of file res_phoneprov.c.

378 {
379  if (!providers) {
380  return;
381  }
382 
384 }

References ao2_callback, NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, and providers.

Referenced by unload_module().

◆ delete_routes()

static void delete_routes ( void  )
static

Delete all http routes, freeing their memory.

Definition at line 497 of file res_phoneprov.c.

498 {
499  if (!http_routes) {
500  return;
501  }
502 
504 }

References ao2_callback, http_routes, NULL, OBJ_MULTIPLE, OBJ_NODATA, and OBJ_UNLINK.

Referenced by unload_module().

◆ delete_users()

static void delete_users ( void  )
static

Delete all users.

Definition at line 774 of file res_phoneprov.c.

775 {
776  if (!users) {
777  return;
778  }
779 
781 }

References ao2_callback, NULL, OBJ_MULTIPLE, OBJ_NODATA, and OBJ_UNLINK.

Referenced by unload_module().

◆ extension_delete_cb()

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

Definition at line 1581 of file res_phoneprov.c.

1582 {
1583  struct user *user = obj;
1584  char *provider_name = data;
1585  char *macaddress = arg;
1586 
1587  if (!strcmp(user->provider_name, provider_name) && !strcasecmp(user->macaddress, macaddress)) {
1588  return CMP_MATCH;
1589  }
1590  return 0;
1591 }
@ CMP_MATCH
Definition: astobj2.h:1027

References CMP_MATCH, user::macaddress, and user::provider_name.

Referenced by ast_phoneprov_delete_extension().

◆ extensions_delete_cb()

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

Definition at line 1571 of file res_phoneprov.c.

1572 {
1573  char *provider_name = arg;
1574  struct user *user = obj;
1575  if (strcmp(user->provider_name, provider_name)) {
1576  return 0;
1577  }
1578  return CMP_MATCH;
1579 }

References CMP_MATCH, phoneprov_provider::provider_name, and user::provider_name.

Referenced by ast_phoneprov_delete_extensions().

◆ find_profile()

static struct phone_profile* find_profile ( const char *  name)
static

Return a phone profile looked up by name.

Definition at line 544 of file res_phoneprov.c.

545 {
547 }

References ao2_find, name, OBJ_SEARCH_KEY, and profiles.

Referenced by ast_phoneprov_add_extension().

◆ find_provider()

static struct phoneprov_provider* find_provider ( char *  name)
static

Definition at line 371 of file res_phoneprov.c.

372 {
374 }

References ao2_find, name, OBJ_SEARCH_KEY, and providers.

Referenced by ast_phoneprov_add_extension(), and ast_phoneprov_provider_register().

◆ find_user()

static struct user* find_user ( const char *  macaddress)
static

Return a user looked up by name.

Definition at line 735 of file res_phoneprov.c.

736 {
737  return ao2_find(users, macaddress, OBJ_SEARCH_KEY);
738 }

References ao2_find, user::macaddress, and OBJ_SEARCH_KEY.

Referenced by ast_phoneprov_add_extension(), and pp_each_extension_helper().

◆ get_defaults()

static struct varshead* get_defaults ( void  )
static

Definition at line 1199 of file res_phoneprov.c.

1200 {
1201  struct ast_config *phoneprov_cfg, *cfg = CONFIG_STATUS_FILEINVALID;
1202  const char *value;
1203  struct ast_variable *v;
1204  struct ast_var_t *var;
1205  struct ast_flags config_flags = { 0 };
1206  struct varshead *defaults = ast_var_list_create();
1207 
1208  if (!defaults) {
1209  ast_log(LOG_ERROR, "Unable to create default var list.\n");
1210  return NULL;
1211  }
1212 
1213  if (!(phoneprov_cfg = ast_config_load("phoneprov.conf", config_flags))
1214  || phoneprov_cfg == CONFIG_STATUS_FILEINVALID) {
1215  ast_log(LOG_ERROR, "Unable to load config phoneprov.conf\n");
1216  ast_var_list_destroy(defaults);
1217  return NULL;
1218  }
1219 
1221  if (!value) {
1222  struct in_addr addr;
1224  if (value) {
1225  lookup_iface(value, &addr);
1226  value = ast_inet_ntoa(addr);
1227  }
1228  }
1229  if (value) {
1231  AST_VAR_LIST_INSERT_TAIL(defaults, var);
1232  } else {
1233  ast_log(LOG_WARNING, "Unable to find a valid server address or name.\n");
1234  }
1235 
1237  if (!value) {
1238  if ((cfg = ast_config_load("sip.conf", config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) {
1239  value = ast_variable_retrieve(cfg, "general", "bindport");
1240  }
1241  }
1243  if (cfg && cfg != CONFIG_STATUS_FILEINVALID) {
1244  ast_config_destroy(cfg);
1245  }
1246  AST_VAR_LIST_INSERT_TAIL(defaults, var);
1247 
1249  if (!value) {
1250  ast_log(LOG_ERROR, "Unable to load default profile.\n");
1251  ast_config_destroy(phoneprov_cfg);
1252  ast_var_list_destroy(defaults);
1253  return NULL;
1254  }
1256  AST_VAR_LIST_INSERT_TAIL(defaults, var);
1257  ast_config_destroy(phoneprov_cfg);
1258 
1259  if (!(cfg = ast_config_load("users.conf", config_flags)) || cfg == CONFIG_STATUS_FILEINVALID) {
1260  ast_log(LOG_ERROR, "Unable to load users.conf\n");
1261  ast_var_list_destroy(defaults);
1262  return NULL;
1263  }
1264 
1265  /* Go ahead and load global variables from users.conf so we can append to profiles */
1266  for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
1267  if (!strcasecmp(v->name, pp_user_lookup[AST_PHONEPROV_STD_VOICEMAIL_EXTEN])) {
1269  AST_VAR_LIST_INSERT_TAIL(defaults, var);
1270  }
1271  if (!strcasecmp(v->name, pp_user_lookup[AST_PHONEPROV_STD_EXTENSION_LENGTH])) {
1273  AST_VAR_LIST_INSERT_TAIL(defaults, var);
1274  }
1275  }
1276  ast_config_destroy(cfg);
1277 
1278  return defaults;
1279 }
#define ast_config_load(filename, flags)
Load a config file.
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:768
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: main/utils.c:928
@ AST_PHONEPROV_STD_SERVER_IFACE
Definition: phoneprov.h:42
@ AST_PHONEPROV_STD_SERVER_PORT
Definition: phoneprov.h:41
@ AST_PHONEPROV_STD_SERVER
Definition: phoneprov.h:40
@ AST_PHONEPROV_STD_EXTENSION_LENGTH
Definition: phoneprov.h:44
@ AST_PHONEPROV_STD_VOICEMAIL_EXTEN
Definition: phoneprov.h:43
static const char * pp_general_lookup[]
static const char * pp_user_lookup[]
static int lookup_iface(const char *iface, struct in_addr *address)
Structure used to handle boolean flags.
Definition: utils.h:199
Structure for variables, used for configurations and for channel variables.
int value
Definition: syslog.c:37

References ast_config_destroy(), ast_config_load, ast_inet_ntoa(), ast_log, AST_PHONEPROV_STD_EXTENSION_LENGTH, AST_PHONEPROV_STD_PROFILE, AST_PHONEPROV_STD_SERVER, AST_PHONEPROV_STD_SERVER_IFACE, AST_PHONEPROV_STD_SERVER_PORT, AST_PHONEPROV_STD_VOICEMAIL_EXTEN, ast_var_assign, ast_var_list_create(), ast_var_list_destroy(), AST_VAR_LIST_INSERT_TAIL(), ast_variable_browse(), ast_variable_retrieve(), CONFIG_STATUS_FILEINVALID, LOG_ERROR, LOG_WARNING, lookup_iface(), ast_variable::name, ast_variable::next, NULL, pp_general_lookup, pp_user_lookup, S_OR, ast_variable::value, value, var, and variable_lookup.

Referenced by load_users().

◆ handle_show_routes()

static char* handle_show_routes ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

CLI command to list static and dynamic routes.

Definition at line 1157 of file res_phoneprov.c.

1158 {
1159  int fd = a->fd;
1160  switch(cmd) {
1161  case CLI_INIT:
1162  e->command = "phoneprov show routes";
1163  e->usage =
1164  "Usage: phoneprov show routes\n"
1165  " Lists all registered phoneprov http routes.\n";
1166  return NULL;
1167  case CLI_GENERATE:
1168  return NULL;
1169  }
1170 
1171  /* This currently iterates over routes twice, but it is the only place I've needed
1172  * to really separate static an dynamic routes, so I've just left it this way. */
1173  ast_cli(a->fd, "Static routes\n\n");
1174  ast_cli(a->fd, FORMATS, "Profile", "Relative URI", "Physical location");
1175 
1177 
1178  ast_cli(a->fd, "\nDynamic routes\n\n");
1179  ast_cli(a->fd, FORMATD, "Provider", "Profile", "Relative URI", "Template");
1180 
1182 
1183  return CLI_SUCCESS;
1184 }
#define CLI_SUCCESS
Definition: cli.h:44
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
#define FORMATS
static int route_list_cb(void *obj, void *arg, void *data, int flags)
#define FORMATD
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
static struct test_val a

References a, ao2_callback_data, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, FORMATD, FORMATS, http_routes, NULL, OBJ_MULTIPLE, OBJ_NODATA, route_list_cb(), and ast_cli_entry::usage.

◆ load_common()

static int load_common ( void  )
static

Definition at line 1351 of file res_phoneprov.c.

1352 {
1353  struct ast_config *phoneprov_cfg;
1354  struct ast_flags config_flags = { 0 };
1355  char *cat;
1356 
1357  if (!(phoneprov_cfg = ast_config_load("phoneprov.conf", config_flags))
1358  || phoneprov_cfg == CONFIG_STATUS_FILEINVALID) {
1359  ast_log(LOG_ERROR, "Unable to load config phoneprov.conf\n");
1360  return -1;
1361  }
1362 
1363  cat = NULL;
1364  while ((cat = ast_category_browse(phoneprov_cfg, cat))) {
1365  if (!strcasecmp(cat, "general")) {
1366  continue;
1367  }
1368  build_profile(cat, ast_variable_browse(phoneprov_cfg, cat));
1369  }
1370  ast_config_destroy(phoneprov_cfg);
1371 
1372  if (!ao2_container_count(profiles)) {
1373  ast_log(LOG_ERROR, "There are no provisioning profiles in phoneprov.conf.\n");
1374  return -1;
1375  }
1376 
1377  return 0;
1378 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3327
static void build_profile(const char *name, struct ast_variable *v)
Build a phone profile and add it to the list of phone profiles.

References ao2_container_count(), ast_category_browse(), ast_config_destroy(), ast_config_load, ast_log, ast_variable_browse(), build_profile(), CONFIG_STATUS_FILEINVALID, LOG_ERROR, NULL, and profiles.

Referenced by load_module().

◆ load_file()

static int load_file ( const char *  filename,
char **  ret 
)
static

Read a TEXT file into a string and return the length.

Definition at line 399 of file res_phoneprov.c.

400 {
401  int len = 0;
402  FILE *f;
403 
404  if (!(f = fopen(filename, "r"))) {
405  *ret = NULL;
406  return -1;
407  }
408 
409  fseek(f, 0, SEEK_END);
410  len = ftell(f);
411  fseek(f, 0, SEEK_SET);
412  if (!(*ret = ast_malloc(len + 1))) {
413  fclose(f);
414  return -2;
415  }
416 
417  if (len != fread(*ret, sizeof(char), len, f)) {
418  fclose(f);
419  ast_free(*ret);
420  *ret = NULL;
421  return -3;
422  }
423 
424  fclose(f);
425 
426  (*ret)[len] = '\0';
427 
428  return len;
429 }
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

References ast_free, ast_malloc, len(), and NULL.

Referenced by make_ari_stubs::main(), phoneprov_callback(), and pp_each_extension_helper().

◆ load_module()

static int load_module ( void  )
static

Load the module.

Module loading including tests for configuration or dependencies. This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails tests return AST_MODULE_LOAD_FAILURE. If the module can not load the configuration file or other non-critical problem return AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.

Definition at line 1417 of file res_phoneprov.c.

1418 {
1420  phone_profile_hash_fn, NULL, phone_profile_cmp_fn);
1421  if (!profiles) {
1422  ast_log(LOG_ERROR, "Unable to allocate profiles container.\n");
1423  return AST_MODULE_LOAD_DECLINE;
1424  }
1425 
1427  http_route_hash_fn, NULL, http_route_cmp_fn);
1428  if (!http_routes) {
1429  ast_log(LOG_ERROR, "Unable to allocate routes container.\n");
1430  goto error;
1431  }
1432 
1433  if (load_common()) {
1434  ast_log(LOG_ERROR, "Unable to load provisioning profiles.\n");
1435  goto error;
1436  }
1437 
1439  user_hash_fn, NULL, user_cmp_fn);
1440  if (!users) {
1441  ast_log(LOG_ERROR, "Unable to allocate users container.\n");
1442  goto error;
1443  }
1444 
1446  MAX_PROVIDER_BUCKETS, phoneprov_provider_hash_fn, NULL, phoneprov_provider_cmp_fn);
1447  if (!providers) {
1448  ast_log(LOG_ERROR, "Unable to allocate providers container.\n");
1449  goto error;
1450  }
1451 
1452  /* Register ourselves as the provider for sip.conf/users.conf */
1454  ast_log(LOG_WARNING, "Unable register sip/users config provider. Others may succeed.\n");
1455  }
1456 
1458 
1462 
1463  return AST_MODULE_LOAD_SUCCESS;
1464 
1465 error:
1466  unload_module();
1467  return AST_MODULE_LOAD_DECLINE;
1468 }
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
int ast_http_uri_link(struct ast_http_uri *urihandler)
Register a URI handler.
Definition: http.c:676
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1543
#define MAX_USER_BUCKETS
Definition: res_phoneprov.c:83
#define MAX_ROUTE_BUCKETS
Definition: res_phoneprov.c:82
#define MAX_PROFILE_BUCKETS
Definition: res_phoneprov.c:81
#define MAX_PROVIDER_BUCKETS
Definition: res_phoneprov.c:80
static struct ast_custom_function pp_each_extension_function
static int load_common(void)
static struct ast_cli_entry pp_cli[]
static struct ast_custom_function pp_each_user_function
static struct ast_http_uri phoneprovuri
#define SIPUSERS_PROVIDER_NAME
static int unload_module(void)
int ast_phoneprov_provider_register(char *provider_name, ast_phoneprov_load_users_cb load_users)
Registers a config provider to phoneprov.
int error(const char *format,...)
Definition: utils/frame.c:999
#define ARRAY_LEN(a)
Definition: utils.h:661

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ARRAY_LEN, ast_cli_register_multiple, ast_custom_function_register, ast_http_uri_link(), ast_log, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_phoneprov_provider_register(), error(), http_routes, load_common(), load_users(), LOG_ERROR, LOG_WARNING, MAX_PROFILE_BUCKETS, MAX_PROVIDER_BUCKETS, MAX_ROUTE_BUCKETS, MAX_USER_BUCKETS, NULL, phoneprovuri, pp_cli, pp_each_extension_function, pp_each_user_function, profiles, providers, SIPUSERS_PROVIDER_NAME, and unload_module().

◆ load_users()

static int load_users ( void  )
static

Definition at line 1281 of file res_phoneprov.c.

1282 {
1283  struct ast_config *cfg;
1284  char *cat;
1285  const char *value;
1286  struct ast_flags config_flags = { 0 };
1287  struct varshead *defaults = get_defaults();
1288 
1289  if (!defaults) {
1290  ast_log(LOG_WARNING, "Unable to load default variables.\n");
1291  return -1;
1292  }
1293 
1294  if (!(cfg = ast_config_load("users.conf", config_flags))
1295  || cfg == CONFIG_STATUS_FILEINVALID) {
1296  ast_log(LOG_WARNING, "Unable to load users.conf\n");
1297  ast_var_list_destroy(defaults);
1298  return -1;
1299  }
1300 
1301  cat = NULL;
1302  while ((cat = ast_category_browse(cfg, cat))) {
1303  const char *tmp;
1304  int i;
1305  struct ast_var_t *varx;
1306  struct ast_var_t *vard;
1307 
1308  if (strcasecmp(cat, "general") && strcasecmp(cat, "authentication")) {
1309  struct varshead *variables = ast_var_list_create();
1310 
1311  if (!((tmp = ast_variable_retrieve(cfg, cat, "autoprov")) && ast_true(tmp))) {
1312  ast_var_list_destroy(variables);
1313  continue;
1314  }
1315 
1316  /* Transfer the standard variables */
1317  for (i = 0; i < AST_PHONEPROV_STD_VAR_LIST_LENGTH; i++) {
1318  if (pp_user_lookup[i]) {
1319  value = ast_variable_retrieve(cfg, cat, pp_user_lookup[i]);
1320  if (value) {
1321  varx = ast_var_assign(variable_lookup[i],
1322  value);
1323  AST_VAR_LIST_INSERT_TAIL(variables, varx);
1324  }
1325  }
1326  }
1327 
1329  ast_log(LOG_WARNING, "autoprov set for %s, but no mac address - skipping.\n", cat);
1330  ast_var_list_destroy(variables);
1331  continue;
1332  }
1333 
1334  /* Apply defaults */
1335  AST_VAR_LIST_TRAVERSE(defaults, vard) {
1336  if (ast_var_find(variables, vard->name)) {
1337  continue;
1338  }
1339  varx = ast_var_assign(vard->name, vard->value);
1340  AST_VAR_LIST_INSERT_TAIL(variables, varx);
1341  }
1342 
1344  }
1345  }
1346  ast_config_destroy(cfg);
1347  ast_var_list_destroy(defaults);
1348  return 0;
1349 }
static struct varshead * get_defaults(void)
int ast_phoneprov_add_extension(char *provider_name, struct varshead *vars)
Adds an extension.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: main/utils.c:2097

References ast_category_browse(), ast_config_destroy(), ast_config_load, ast_log, ast_phoneprov_add_extension(), AST_PHONEPROV_STD_MAC, AST_PHONEPROV_STD_VAR_LIST_LENGTH, ast_true(), ast_var_assign, ast_var_find(), ast_var_list_create(), ast_var_list_destroy(), AST_VAR_LIST_INSERT_TAIL(), AST_VAR_LIST_TRAVERSE, ast_variable_retrieve(), CONFIG_STATUS_FILEINVALID, get_defaults(), LOG_WARNING, ast_var_t::name, NULL, pp_user_lookup, SIPUSERS_PROVIDER_NAME, tmp(), ast_var_t::value, value, and variable_lookup.

Referenced by ast_phoneprov_provider_register(), and load_module().

◆ lookup_iface()

static int lookup_iface ( const char *  iface,
struct in_addr *  address 
)
static

Definition at line 341 of file res_phoneprov.c.

342 {
343  int mysock, res = 0;
344  struct ifreq ifr;
345  struct sockaddr_in *sin;
346 
347  memset(&ifr, 0, sizeof(ifr));
348  ast_copy_string(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
349 
350  mysock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
351  if (mysock < 0) {
352  ast_log(LOG_ERROR, "Failed to create socket: %s\n", strerror(errno));
353  return -1;
354  }
355 
356  res = ioctl(mysock, SIOCGIFADDR, &ifr);
357 
358  close(mysock);
359 
360  if (res < 0) {
361  ast_log(LOG_WARNING, "Unable to get IP of %s: %s\n", iface, strerror(errno));
362  memcpy(address, &__ourip, sizeof(__ourip));
363  return -1;
364  } else {
365  sin = (struct sockaddr_in *)&ifr.ifr_addr;
366  memcpy(address, &sin->sin_addr, sizeof(*address));
367  return 0;
368  }
369 }
char * address
Definition: f2c.h:59
int errno
static struct in_addr __ourip
for use in lookup_iface
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:406

References __ourip, ast_copy_string(), ast_log, errno, LOG_ERROR, and LOG_WARNING.

Referenced by get_defaults().

◆ phoneprov_callback()

static int phoneprov_callback ( struct ast_tcptls_session_instance ser,
const struct ast_http_uri urih,
const char *  uri,
enum ast_http_method  method,
struct ast_variable get_vars,
struct ast_variable headers 
)
static

Callback that is executed everytime an http request is received by this module.

Definition at line 870 of file res_phoneprov.c.

871 {
872  struct http_route *route;
873  struct ast_str *result;
874  char path[PATH_MAX];
875  char *file = NULL;
876  char *server;
877  int len;
878  int fd;
879  struct ast_str *http_header;
880 
881  if (method != AST_HTTP_GET && method != AST_HTTP_HEAD) {
882  ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method");
883  return 0;
884  }
885 
886  if (!(route = ao2_find(http_routes, uri, OBJ_SEARCH_KEY))) {
887  goto out404;
888  }
889 
890  snprintf(path, sizeof(path), "%s/phoneprov/%s", ast_config_AST_DATA_DIR, route->file->template);
891 
892  if (!route->user) { /* Static file */
893 
894  fd = open(path, O_RDONLY);
895  if (fd < 0) {
896  goto out500;
897  }
898 
899  len = lseek(fd, 0, SEEK_END);
900  lseek(fd, 0, SEEK_SET);
901  if (len < 0) {
902  ast_log(LOG_WARNING, "Could not load file: %s (%d)\n", path, len);
903  close(fd);
904  goto out500;
905  }
906 
907  http_header = ast_str_create(80);
908  ast_str_set(&http_header, 0, "Content-type: %s\r\n",
909  route->file->mime_type);
910 
911  ast_http_send(ser, method, 200, NULL, http_header, NULL, fd, 0);
912 
913  close(fd);
914  route = unref_route(route);
915  return 0;
916  } else { /* Dynamic file */
917  struct ast_str *tmp;
918 
919  len = load_file(path, &file);
920  if (len < 0) {
921  ast_log(LOG_WARNING, "Could not load file: %s (%d)\n", path, len);
922  if (file) {
923  ast_free(file);
924  }
925 
926  goto out500;
927  }
928 
929  if (!file) {
930  goto out500;
931  }
932 
933  if (!(tmp = ast_str_create(len))) {
934  if (file) {
935  ast_free(file);
936  }
937 
938  goto out500;
939  }
940 
941  /* Unless we are overridden by serveriface or serveraddr, we set the SERVER variable to
942  * the IP address we are listening on that the phone contacted for this config file */
943 
944  server = ast_var_find(AST_LIST_FIRST(&route->user->extensions)->headp,
946 
947  if (!server) {
948  union {
949  struct sockaddr sa;
950  struct sockaddr_in sa_in;
951  } name;
952  socklen_t namelen = sizeof(name.sa);
953  int res;
954 
955  if ((res = getsockname(ast_iostream_get_fd(ser->stream), &name.sa, &namelen))) {
956  ast_log(LOG_WARNING, "Could not get server IP, breakage likely.\n");
957  } else {
958  struct extension *exten_iter;
959  const char *newserver = ast_inet_ntoa(name.sa_in.sin_addr);
960 
961  AST_LIST_TRAVERSE(&route->user->extensions, exten_iter, entry) {
962  AST_VAR_LIST_INSERT_TAIL(exten_iter->headp,
964  }
965  }
966  }
967 
969 
970  ast_free(file);
971 
972  http_header = ast_str_create(80);
973  ast_str_set(&http_header, 0, "Content-type: %s\r\n",
974  route->file->mime_type);
975 
976  if (!(result = ast_str_create(512))) {
977  ast_log(LOG_ERROR, "Could not create result string!\n");
978  if (tmp) {
979  ast_free(tmp);
980  }
981  ast_free(http_header);
982  goto out500;
983  }
985 
986  ast_http_send(ser, method, 200, NULL, http_header, result, 0, 0);
987  ast_free(tmp);
988 
989  route = unref_route(route);
990 
991  return 0;
992  }
993 
994 out404:
995  ast_http_error(ser, 404, "Not Found", uri);
996  return 0;
997 
998 out500:
999  route = unref_route(route);
1000  ast_http_error(ser, 500, "Internal Error", "An internal error has occured.");
1001  return 0;
1002 }
#define PATH_MAX
Definition: asterisk.h:40
static PGresult * result
Definition: cel_pgsql.c:84
void ast_http_send(struct ast_tcptls_session_instance *ser, enum ast_http_method method, int status_code, const char *status_title, struct ast_str *http_header, struct ast_str *out, int fd, unsigned int static_content)
Generic function for sending HTTP/1.1 response.
Definition: http.c:459
@ AST_HTTP_GET
Definition: http.h:60
@ AST_HTTP_HEAD
Definition: http.h:62
void ast_http_error(struct ast_tcptls_session_instance *ser, int status, const char *title, const char *text)
Send HTTP error message and close socket.
Definition: http.c:651
int ast_iostream_get_fd(struct ast_iostream *stream)
Get an iostream's file descriptor.
Definition: iostream.c:84
const char * ast_config_AST_DATA_DIR
Definition: options.c:158
static int load_file(const char *filename, char **ret)
Read a TEXT file into a string and return the length.
const char * method
Definition: res_pjsip.c:1130
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:1117
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1091
struct ast_iostream * stream
Definition: tcptls.h:161
struct varshead * headp
const ast_string_field template

References ao2_find, ast_config_AST_DATA_DIR, ast_free, ast_http_error(), AST_HTTP_GET, AST_HTTP_HEAD, ast_http_send(), ast_inet_ntoa(), ast_iostream_get_fd(), AST_LIST_FIRST, AST_LIST_TRAVERSE, ast_log, AST_PHONEPROV_STD_SERVER, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_str_substitute_variables_varshead(), ast_var_assign, ast_var_find(), AST_VAR_LIST_INSERT_TAIL(), user::extensions, http_route::file, make_ari_stubs::file, extension::headp, http_routes, len(), load_file(), LOG_ERROR, LOG_WARNING, method, phoneprov_file::mime_type, name, NULL, OBJ_SEARCH_KEY, PATH_MAX, result, ast_tcptls_session_instance::stream, phoneprov_file::template, tmp(), unref_route(), http_route::user, and variable_lookup.

◆ pp_each_extension_helper()

static int pp_each_extension_helper ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
struct ast_str **  bufstr,
int  len 
)
static

A dialplan function that can be used to output a template for each extension attached to a user.

Definition at line 1062 of file res_phoneprov.c.

1063 {
1064  struct user *user;
1065  struct extension *exten;
1066  char path[PATH_MAX];
1067  char *file;
1068  int filelen;
1069  struct ast_str *str;
1071  AST_APP_ARG(mac);
1072  AST_APP_ARG(template);
1073  );
1074 
1075  AST_STANDARD_APP_ARGS(args, data);
1076 
1077  if (ast_strlen_zero(args.mac) || ast_strlen_zero(args.template)) {
1078  ast_log(LOG_WARNING, "PP_EACH_EXTENSION requires both a macaddress and template filename.\n");
1079  return 0;
1080  }
1081 
1082  if (!(user = find_user(args.mac))) {
1083  ast_log(LOG_WARNING, "Could not find user with mac = '%s'\n", args.mac);
1084  return 0;
1085  }
1086 
1087  snprintf(path, sizeof(path), "%s/phoneprov/%s", ast_config_AST_DATA_DIR, args.template);
1088  filelen = load_file(path, &file);
1089  if (filelen < 0) {
1090  ast_log(LOG_WARNING, "Could not load file: %s (%d)\n", path, filelen);
1091  if (file) {
1092  ast_free(file);
1093  }
1094  return 0;
1095  }
1096 
1097  if (!file) {
1098  return 0;
1099  }
1100 
1101  if (!(str = ast_str_create(filelen))) {
1102  return 0;
1103  }
1104 
1107  if (buf) {
1108  size_t slen = len;
1109  ast_build_string(&buf, &slen, "%s", ast_str_buffer(str));
1110  } else {
1111  ast_str_append(bufstr, len, "%s", ast_str_buffer(str));
1112  }
1113  }
1114 
1115  ast_free(file);
1116  ast_free(str);
1117 
1118  user = unref_user(user);
1119 
1120  return 0;
1121 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int ast_build_string(char **buffer, size_t *space, const char *fmt,...)
Build a string in a buffer, designed to be called repeatedly.
Definition: main/utils.c:2065

References args, AST_APP_ARG, ast_build_string(), ast_config_AST_DATA_DIR, AST_DECLARE_APP_ARGS, ast_free, AST_LIST_TRAVERSE, ast_log, AST_STANDARD_APP_ARGS, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_substitute_variables_varshead(), ast_strlen_zero(), buf, exten, user::extensions, make_ari_stubs::file, find_user(), len(), load_file(), LOG_WARNING, PATH_MAX, str, unref_user(), and user.

Referenced by pp_each_extension_read().

◆ pp_each_extension_read()

static int pp_each_extension_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)
static

Definition at line 1123 of file res_phoneprov.c.

1124 {
1125  return pp_each_extension_helper(chan, cmd, data, buf, NULL, len);
1126 }
static int pp_each_extension_helper(struct ast_channel *chan, const char *cmd, char *data, char *buf, struct ast_str **bufstr, int len)
A dialplan function that can be used to output a template for each extension attached to a user.

References buf, len(), NULL, and pp_each_extension_helper().

◆ pp_each_extension_read2()

static int pp_each_extension_read2 ( struct ast_channel chan,
const char *  cmd,
char *  data,
struct ast_str **  buf,
ssize_t  len 
)
static

Definition at line 1128 of file res_phoneprov.c.

1129 {
1130  return pp_each_extension_helper(chan, cmd, data, NULL, buf, len);
1131 }

◆ pp_each_user_helper()

static int pp_each_user_helper ( struct ast_channel chan,
char *  data,
char *  buf,
struct ast_str **  bufstr,
int  len 
)
static

A dialplan function that can be used to print a string for each phoneprov user.

Definition at line 1005 of file res_phoneprov.c.

1006 {
1007  char *tmp;
1008  struct ao2_iterator i;
1009  struct user *user;
1010  struct ast_str *str;
1012  AST_APP_ARG(string);
1013  AST_APP_ARG(exclude_mac);
1014  );
1015  AST_STANDARD_APP_ARGS(args, data);
1016 
1017  if (!(str = ast_str_create(16))) {
1018  return -1;
1019  }
1020 
1021  /* Fix data by turning %{ into ${ */
1022  while ((tmp = strstr(args.string, "%{")))
1023  *tmp = '$';
1024 
1025  i = ao2_iterator_init(users, 0);
1026  while ((user = ao2_iterator_next(&i))) {
1027  if (!ast_strlen_zero(args.exclude_mac) && !strcasecmp(user->macaddress, args.exclude_mac)) {
1028  continue;
1029  }
1031  if (buf) {
1032  size_t slen = len;
1033  ast_build_string(&buf, &slen, "%s", ast_str_buffer(str));
1034  } else {
1035  ast_str_append(bufstr, len, "%s", ast_str_buffer(str));
1036  }
1037  user = unref_user(user);
1038  }
1040 
1041  ast_free(str);
1042  return 0;
1043 }
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, args, AST_APP_ARG, ast_build_string(), AST_DECLARE_APP_ARGS, ast_free, AST_LIST_FIRST, AST_STANDARD_APP_ARGS, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_substitute_variables_varshead(), ast_strlen_zero(), buf, user::extensions, len(), user::macaddress, str, tmp(), unref_user(), and user.

Referenced by pp_each_user_read().

◆ pp_each_user_read()

static int pp_each_user_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)
static

Definition at line 1045 of file res_phoneprov.c.

1046 {
1047  return pp_each_user_helper(chan, data, buf, NULL, len);
1048 }
static int pp_each_user_helper(struct ast_channel *chan, char *data, char *buf, struct ast_str **bufstr, int len)
A dialplan function that can be used to print a string for each phoneprov user.

References buf, len(), NULL, and pp_each_user_helper().

◆ pp_each_user_read2()

static int pp_each_user_read2 ( struct ast_channel chan,
const char *  cmd,
char *  data,
struct ast_str **  buf,
ssize_t  len 
)
static

Definition at line 1050 of file res_phoneprov.c.

1051 {
1052  return pp_each_user_helper(chan, data, NULL, buf, len);
1053 }

◆ profile_destructor()

static void profile_destructor ( void *  obj)
static

Definition at line 549 of file res_phoneprov.c.

550 {
551  struct phone_profile *profile = obj;
552  struct phoneprov_file *file;
553  struct ast_var_t *var;
554 
555  while ((file = AST_LIST_REMOVE_HEAD(&profile->static_files, entry))) {
556  delete_file(file);
557  }
558 
559  while ((file = AST_LIST_REMOVE_HEAD(&profile->dynamic_files, entry))) {
560  delete_file(file);
561  }
562 
563  while ((var = AST_LIST_REMOVE_HEAD(profile->headp, entries))) {
565  }
566 
567  ast_free(profile->headp);
569 }
void ast_var_delete(struct ast_var_t *var)
Definition: extconf.c:2472
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
static void delete_file(struct phoneprov_file *file)
struct ast_var_t::@239 entries

References ast_free, AST_LIST_REMOVE_HEAD, ast_string_field_free_memory, ast_var_delete(), delete_file(), phone_profile::dynamic_files, ast_var_t::entries, make_ari_stubs::file, phone_profile::headp, phone_profile::static_files, and var.

Referenced by build_profile().

◆ provider_destructor()

static void provider_destructor ( void *  obj)
static

Definition at line 386 of file res_phoneprov.c.

387 {
388  struct phoneprov_provider *provider = obj;
390 }

References ast_string_field_free_memory, and provider.

Referenced by ast_phoneprov_provider_register().

◆ reload()

static int reload ( void  )
static

Definition at line 1470 of file res_phoneprov.c.

1471 {
1472  struct ao2_iterator i;
1473  struct phoneprov_provider *provider;
1474 
1475  /* Clean everything except the providers */
1476  delete_routes();
1477  delete_users();
1478  delete_profiles();
1479 
1480  /* Reload the profiles */
1481  if (load_common()) {
1482  ast_log(LOG_ERROR, "Unable to reload provisioning profiles.\n");
1483  unload_module();
1484  return AST_MODULE_LOAD_DECLINE;
1485  }
1486 
1487  /* For each provider, reload the users */
1489  i = ao2_iterator_init(providers, 0);
1490  for(; (provider = ao2_iterator_next(&i)); ao2_ref(provider, -1)) {
1491  if (provider->load_users()) {
1492  ast_log(LOG_ERROR, "Unable to load provider '%s' users. Reload aborted.\n", provider->provider_name);
1493  continue;
1494  }
1495  }
1498 
1499  return AST_MODULE_LOAD_SUCCESS;
1500 }
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
static void delete_profiles(void)
Delete all phone profiles, freeing their memory.
static void delete_routes(void)
Delete all http routes, freeing their memory.
static void delete_users(void)
Delete all users.

◆ route_destructor()

static void route_destructor ( void *  obj)
static

Definition at line 489 of file res_phoneprov.c.

490 {
491  struct http_route *route = obj;
492 
494 }

References ast_string_field_free_memory.

Referenced by build_route().

◆ route_list_cb()

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

Definition at line 1141 of file res_phoneprov.c.

1142 {
1143  int fd = *(int *)arg;
1144  struct http_route *route = obj;
1145 
1146  if (data && route->user) {
1147  ast_cli(fd, FORMATD, route->user->provider_name, route->profile->name, route->uri, route->file->template);
1148  }
1149  if (!data && !route->user) {
1150  ast_cli(fd, FORMATS, route->profile->name, route->uri, route->file->template);
1151  }
1152 
1153  return CMP_MATCH;
1154 }
const ast_string_field name

References ast_cli(), CMP_MATCH, http_route::file, FORMATD, FORMATS, phone_profile::name, http_route::profile, user::provider_name, phoneprov_file::template, http_route::uri, and http_route::user.

Referenced by handle_show_routes().

◆ routes_delete_cb()

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

Definition at line 740 of file res_phoneprov.c.

741 {
742  struct http_route *route = obj;
743  struct user *user = route->user;
744  char *macaddress = arg;
745 
746  if (user && !strcmp(user->macaddress, macaddress)) {
747  return CMP_MATCH;
748  }
749  return 0;
750 }

References CMP_MATCH, user::macaddress, and http_route::user.

Referenced by user_destructor().

◆ set_timezone_variables()

static void set_timezone_variables ( struct varshead headp,
const char *  zone 
)
static

Set all timezone-related variables based on a zone (i.e. America/New_York)

Parameters
headppointer to list of user variables
zoneA time zone. NULL sets variables based on timezone of the machine

Definition at line 435 of file res_phoneprov.c.

436 {
437  time_t utc_time;
438  int dstenable;
439  time_t dststart;
440  time_t dstend;
441  struct ast_tm tm_info;
442  int tzoffset;
443  char buffer[21];
444  struct timeval when;
445 
446  time(&utc_time);
447  ast_get_dst_info(&utc_time, &dstenable, &dststart, &dstend, &tzoffset, zone);
448  snprintf(buffer, sizeof(buffer), "%d", tzoffset);
449  AST_VAR_LIST_INSERT_TAIL(headp, ast_var_assign("TZOFFSET", buffer));
450 
451  if (!dstenable) {
452  return;
453  }
454 
455  AST_VAR_LIST_INSERT_TAIL(headp, ast_var_assign("DST_ENABLE", "1"));
456 
457  when.tv_sec = dststart;
458  ast_localtime(&when, &tm_info, zone);
459 
460  snprintf(buffer, sizeof(buffer), "%d", tm_info.tm_mon+1);
461  AST_VAR_LIST_INSERT_TAIL(headp, ast_var_assign("DST_START_MONTH", buffer));
462 
463  snprintf(buffer, sizeof(buffer), "%d", tm_info.tm_mday);
464  AST_VAR_LIST_INSERT_TAIL(headp, ast_var_assign("DST_START_MDAY", buffer));
465 
466  snprintf(buffer, sizeof(buffer), "%d", tm_info.tm_hour);
467  AST_VAR_LIST_INSERT_TAIL(headp, ast_var_assign("DST_START_HOUR", buffer));
468 
469  when.tv_sec = dstend;
470  ast_localtime(&when, &tm_info, zone);
471 
472  snprintf(buffer, sizeof(buffer), "%d", tm_info.tm_mon + 1);
473  AST_VAR_LIST_INSERT_TAIL(headp, ast_var_assign("DST_END_MONTH", buffer));
474 
475  snprintf(buffer, sizeof(buffer), "%d", tm_info.tm_mday);
476  AST_VAR_LIST_INSERT_TAIL(headp, ast_var_assign("DST_END_MDAY", buffer));
477 
478  snprintf(buffer, sizeof(buffer), "%d", tm_info.tm_hour);
479  AST_VAR_LIST_INSERT_TAIL(headp, ast_var_assign("DST_END_HOUR", buffer));
480 }
void ast_get_dst_info(const time_t *const timep, int *dst_enabled, time_t *dst_start, time_t *dst_end, int *gmt_off, const char *const zone)
Definition: localtime.c:1754
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739

References ast_get_dst_info(), ast_localtime(), ast_var_assign, AST_VAR_LIST_INSERT_TAIL(), ast_tm::tm_hour, ast_tm::tm_mday, and ast_tm::tm_mon.

Referenced by build_extension().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1380 of file res_phoneprov.c.

1381 {
1386 
1387  /* This cleans up the sip.conf/users.conf provider (called specifically for clarity) */
1389 
1390  /* This cleans up the framework which also cleans up the providers. */
1391  delete_profiles();
1393  profiles = NULL;
1394  delete_routes();
1395  delete_users();
1397  http_routes = NULL;
1398  ao2_cleanup(users);
1399  users = NULL;
1400  delete_providers();
1402  providers = NULL;
1403 
1404  return 0;
1405 }
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
void ast_http_uri_unlink(struct ast_http_uri *urihandler)
Unregister a URI handler.
Definition: http.c:708
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
static void delete_providers(void)
Delete all providers.

References ao2_cleanup, ARRAY_LEN, ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_http_uri_unlink(), ast_phoneprov_provider_unregister(), delete_profiles(), delete_providers(), delete_routes(), delete_users(), http_routes, NULL, phoneprovuri, pp_cli, pp_each_extension_function, pp_each_user_function, profiles, providers, and SIPUSERS_PROVIDER_NAME.

Referenced by load_module().

◆ unref_profile()

static struct phone_profile* unref_profile ( struct phone_profile prof)
static

Definition at line 536 of file res_phoneprov.c.

537 {
538  ao2_cleanup(prof);
539 
540  return NULL;
541 }

References ao2_cleanup, and NULL.

Referenced by build_profile(), and user_destructor().

◆ unref_route()

static struct http_route* unref_route ( struct http_route route)
static

Definition at line 482 of file res_phoneprov.c.

483 {
484  ao2_cleanup(route);
485 
486  return NULL;
487 }

References ao2_cleanup, and NULL.

Referenced by build_route(), and phoneprov_callback().

◆ unref_user()

static struct user* unref_user ( struct user user)
static

Definition at line 727 of file res_phoneprov.c.

728 {
729  ao2_cleanup(user);
730 
731  return NULL;
732 }

References ao2_cleanup, and NULL.

Referenced by build_user(), pp_each_extension_helper(), and pp_each_user_helper().

◆ user_destructor()

static void user_destructor ( void *  obj)
static

Free all memory associated with a user.

Definition at line 753 of file res_phoneprov.c.

754 {
755  struct user *user = obj;
756  struct extension *exten;
757 
760  }
761 
762  if (user->profile) {
764  }
765 
766  if (http_routes) {
768  }
769 
771 }
static int routes_delete_cb(void *obj, void *arg, int flags)

References ao2_callback, AST_LIST_REMOVE_HEAD, ast_string_field_free_memory, delete_extension(), exten, user::extensions, http_routes, user::macaddress, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, user::profile, routes_delete_cb(), and unref_profile().

Referenced by build_user().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "HTTP Phone Provisioning" , .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_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DEPEND, .requires = "http", }
static

Definition at line 1470 of file res_phoneprov.c.

◆ __ourip

struct in_addr __ourip = { .s_addr = 0x00000000, }
static

for use in lookup_iface

Definition at line 236 of file res_phoneprov.c.

Referenced by lookup_iface().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1509 of file res_phoneprov.c.

◆ http_routes

struct ao2_container* http_routes

◆ phoneprovuri

struct ast_http_uri phoneprovuri
static

Definition at line 1157 of file res_phoneprov.c.

Referenced by load_module(), and unload_module().

◆ pp_cli

struct ast_cli_entry pp_cli[]
static
Initial value:
= {
{ .handler = handle_show_routes , .summary = "Show registered phoneprov http routes" ,},
}
static char * handle_show_routes(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
CLI command to list static and dynamic routes.

Definition at line 1157 of file res_phoneprov.c.

Referenced by load_module(), and unload_module().

◆ pp_each_extension_function

struct ast_custom_function pp_each_extension_function
static
Initial value:
= {
.name = "PP_EACH_EXTENSION",
}
static int pp_each_extension_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int pp_each_extension_read2(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)

Definition at line 1128 of file res_phoneprov.c.

Referenced by load_module(), and unload_module().

◆ pp_each_user_function

struct ast_custom_function pp_each_user_function
static
Initial value:
= {
.name = "PP_EACH_USER",
}
static int pp_each_user_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int pp_each_user_read2(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)

Definition at line 1050 of file res_phoneprov.c.

Referenced by load_module(), and unload_module().

◆ pp_general_lookup

const char* pp_general_lookup[]
static

Definition at line 236 of file res_phoneprov.c.

Referenced by get_defaults().

◆ pp_user_lookup

const char* pp_user_lookup[]
static

Definition at line 209 of file res_phoneprov.c.

Referenced by get_defaults(), and load_users().

◆ profiles

struct ao2_container* profiles

◆ providers

struct ao2_container* providers

◆ users

Definition at line 320 of file res_phoneprov.c.

Referenced by load_users().

◆ variable_lookup

const char* variable_lookup[]
static