Asterisk - The Open Source Telephony Project  21.4.1
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"

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 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 VAR_BUF_SIZE   4096
 

Functions

static int add_user_extension (struct user *user, struct extension *exten)
 Add an extension to a user ordered by index/linenumber.
 
 AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER,"HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
 
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.
 
static int build_user_routes (struct user *user)
 Add an http route for dynamic files attached to the profile of the user.
 
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.
 
static void delete_providers (void)
 Delete all providers.
 
static void delete_routes (void)
 Delete all http routes, freeing their memory.
 
static void delete_users (void)
 Delete all users.
 
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.
 
static struct phoneprov_providerfind_provider (char *name)
 
static struct userfind_user (const char *macaddress)
 Return a user looked up by name.
 
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.
 
static int http_route_cmp_fn (void *obj, void *arg, int flags)
 
static int http_route_hash_fn (const void *obj, const int flags)
 
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.
 
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 phone_profile_cmp_fn (void *obj, void *arg, int flags)
 
static int phone_profile_hash_fn (const void *obj, const int flags)
 
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.
 
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.
 
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.
 
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 int user_cmp_fn (void *obj, void *arg, int flags)
 
static void user_destructor (void *obj)
 Free all memory associated with a user.
 
static int user_hash_fn (const void *obj, const int flags)
 

Variables

static struct in_addr __ourip = { .s_addr = 0x00000000, }
 for use in lookup_iface
 
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

#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.

#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.

Function Documentation

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 1626 of file res_phoneprov.c.

Referenced by users_apply_handler().

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

References CMP_MATCH.

Referenced by phoneprov_destroy().

1598  {
1599  return CMP_MATCH;
1600  }
1601  return 0;
1602 }
1603 
1604 void ast_phoneprov_delete_extension(char *provider_name, char *macaddress)
1605 {
void ast_phoneprov_delete_extension(char *provider_name, char *macaddress)
Deletes an extension.
void ast_phoneprov_delete_extensions ( char *  provider_name)

Deletes all extensions for this provider.

Parameters
provider_nameThe name of the provider

Definition at line 1607 of file res_phoneprov.c.

1615 {
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 1526 of file res_phoneprov.c.

Referenced by load_module().

1526  {
1527  return NULL;
1528  }
1529 
1530  return variable_lookup[var];
1531 }
1532 
1533 int ast_phoneprov_provider_register(char *provider_name,
1534  ast_phoneprov_load_users_cb load_users)
1535 {
1536  struct phoneprov_provider *provider;
1537 
1538  if (ast_strlen_zero(provider_name)) {
1539  ast_log(LOG_ERROR, "Provider name can't be empty.\n");
1540  return -1;
1541  }
1542 
1543  if (!providers) {
1544  ast_log(LOG_WARNING, "Provider '%s' cannot be registered: res_phoneprov not loaded.\n", provider_name);
1545  return -1;
1546  }
1547 
1548  provider = find_provider(provider_name);
1549  if (provider) {
1550  ast_log(LOG_ERROR, "There is already a provider registered named '%s'.\n", provider_name);
1551  ao2_ref(provider, -1);
1552  return -1;
1553  }
1554 
1555  provider = ao2_alloc(sizeof(struct phoneprov_provider), provider_destructor);
1556  if (!provider) {
1557  ast_log(LOG_ERROR, "Unable to allocate sufficient memory for provider '%s'.\n", provider_name);
1558  return -1;
1559  }
1560 
1561  if (ast_string_field_init(provider, 32)) {
1562  ao2_ref(provider, -1);
1563  ast_log(LOG_ERROR, "Unable to allocate sufficient memory for provider '%s' stringfields.\n", provider_name);
1564  return -1;
1565  }
1566 
1567  ast_string_field_set(provider, provider_name, provider_name);
1568  provider->load_users = load_users;
1569 
1570  ao2_link(providers, provider);
1571  ao2_ref(provider, -1);
1572 
1573  if (provider->load_users()) {
int ast_phoneprov_provider_register(char *provider_name, ast_phoneprov_load_users_cb load_users)
Registers a config provider to phoneprov.
structure to hold config providers
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
static int load_users(void)
Callback that loads the users from phoneprov sections.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
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 1616 of file res_phoneprov.c.

1616  {
1617  return;
1618  }
1619 
1620  ao2_callback(users, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, extensions_delete_cb, provider_name);
1621 }
1622 
1623 void ast_phoneprov_provider_unregister(char *provider_name)
1624 {
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Definition: astobj2.h:1693
list of users found in the config file
void ast_phoneprov_provider_unregister(char *provider_name)
Unegisters a config provider from phoneprov and frees its resources.
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 1517 of file res_phoneprov.c.

Referenced by users_apply_handler().

1525 {
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 581 of file res_phoneprov.c.

References ao2_link, 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(), build_route(), phone_profile::default_mime_type, phone_profile::dynamic_files, phoneprov_file::format, phone_profile::headp, phoneprov_file::mime_type, ast_variable::name, ast_variable::next, S_OR, phone_profile::static_files, phone_profile::staticdir, and ast_variable::value.

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  }
const ast_string_field staticdir
struct ast_variable * next
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_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
const ast_string_field format
const char * ast_http_ftype2mtype(const char *ftype) attribute_pure
Return mime type based on extension.
Definition: http.c:206
#define ast_calloc_with_stringfields(n, type, size)
Allocate a structure with embedded stringfields in a single allocation.
Definition: stringfields.h:432
struct phone_profile::@454 static_files
structure to hold file data
struct varshead * headp
const ast_string_field default_mime_type
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
const ast_string_field name
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
structure to hold phone profiles read from phoneprov.conf
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:555
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
#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
Definition: search.h:40
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
struct phone_profile::@455 dynamic_files
const ast_string_field mime_type
#define AST_APP_ARG(name)
Define an application argument.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
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 508 of file res_phoneprov.c.

References ao2_link, ast_string_field_init, ast_string_field_set, http_route::file, phoneprov_file::format, S_OR, and http_route::user.

Referenced by build_profile().

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 
const ast_string_field format
const ast_string_field uri
struct phoneprov_file * file
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
struct user * user
#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
structure to hold http routes (valid URIs, and the files they link to)
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
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 1421 of file res_phoneprov.c.

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ast_cli_register_multiple, ast_custom_function_register, ast_http_uri_link(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_phoneprov_provider_register(), and load_users().

1429 {
1430  profiles = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0, MAX_PROFILE_BUCKETS,
1431  phone_profile_hash_fn, NULL, phone_profile_cmp_fn);
1432  if (!profiles) {
1433  ast_log(LOG_ERROR, "Unable to allocate profiles container.\n");
1434  return AST_MODULE_LOAD_DECLINE;
1435  }
1436 
1437  http_routes = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0, MAX_ROUTE_BUCKETS,
1438  http_route_hash_fn, NULL, http_route_cmp_fn);
1439  if (!http_routes) {
1440  ast_log(LOG_ERROR, "Unable to allocate routes container.\n");
1441  goto error;
1442  }
1443 
1444  if (load_common()) {
1445  ast_log(LOG_ERROR, "Unable to load provisioning profiles.\n");
1446  goto error;
1447  }
1448 
1450  user_hash_fn, NULL, user_cmp_fn);
1451  if (!users) {
1452  ast_log(LOG_ERROR, "Unable to allocate users container.\n");
1453  goto error;
1454  }
1455 
1457  MAX_PROVIDER_BUCKETS, phoneprov_provider_hash_fn, NULL, phoneprov_provider_cmp_fn);
1458  if (!providers) {
1459  ast_log(LOG_ERROR, "Unable to allocate providers container.\n");
1460  goto error;
1461  }
1462 
1463  /* Register ourselves as the provider for users.conf */
1464  if (ast_phoneprov_provider_register(SIPUSERS_PROVIDER_NAME, load_users)) {
1465  ast_log(LOG_WARNING, "Unable register users config provider. Others may succeed.\n");
1466  }
1467 
1468  ast_http_uri_link(&phoneprovuri);
1469 
1470  ast_custom_function_register(&pp_each_user_function);
1471  ast_custom_function_register(&pp_each_extension_function);
1472  ast_cli_register_multiple(pp_cli, ARRAY_LEN(pp_cli));
int ast_phoneprov_provider_register(char *provider_name, ast_phoneprov_load_users_cb load_users)
Registers a config provider to phoneprov.
int ast_http_uri_link(struct ast_http_uri *urihandler)
Register a URI handler.
Definition: http.c:676
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
list of users found in the config file
#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
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static int load_users(void)
Callback that loads the users from phoneprov sections.
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1558
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 431 of file res_phoneprov.c.

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

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));
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

Variable Documentation

struct ast_cli_entry pp_cli[]
static
Initial value:
= {
AST_CLI_DEFINE(handle_show_routes, "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 1195 of file res_phoneprov.c.

struct ast_custom_function pp_each_extension_function
static
Initial value:
= {
.name = "PP_EACH_EXTENSION",
.read = pp_each_extension_read,
.read2 = pp_each_extension_read2,
}

Definition at line 1142 of file res_phoneprov.c.

struct ast_custom_function pp_each_user_function
static
Initial value:
= {
.name = "PP_EACH_USER",
.read = pp_each_user_read,
.read2 = pp_each_user_read2,
}

Definition at line 1064 of file res_phoneprov.c.