parking_devicestate.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2013, Digium, Inc.
  5. *
  6. * Jonathan Rose <jrose@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*! \file
  19. *
  20. * \brief Call Parking Device State Management
  21. *
  22. * \author Jonathan Rose <jrose@digium.com>
  23. */
  24. #include "asterisk.h"
  25. #include "asterisk/logger.h"
  26. #include "res_parking.h"
  27. #include "asterisk/devicestate.h"
  28. struct parking_lot_extension_inuse_search {
  29. char *context;
  30. int exten;
  31. };
  32. static int retrieve_parked_user_targeted(void *obj, void *arg, int flags)
  33. {
  34. int *target = arg;
  35. struct parked_user *user = obj;
  36. if (user->parking_space == *target) {
  37. return CMP_MATCH;
  38. }
  39. return 0;
  40. }
  41. static int parking_lot_search_context_extension_inuse(void *obj, void *arg, int flags)
  42. {
  43. struct parking_lot *lot = obj;
  44. struct parking_lot_extension_inuse_search *search = arg;
  45. RAII_VAR(struct parked_user *, user, NULL, ao2_cleanup);
  46. if (strcmp(lot->cfg->parking_con, search->context)) {
  47. return 0;
  48. }
  49. if ((search->exten < lot->cfg->parking_start) || (search->exten > lot->cfg->parking_stop)) {
  50. return 0;
  51. }
  52. user = ao2_callback(lot->parked_users, 0, retrieve_parked_user_targeted, &search->exten);
  53. if (!user) {
  54. return 0;
  55. }
  56. ao2_lock(user);
  57. if (user->resolution != PARK_UNSET) {
  58. /* The parked user isn't in an answerable state. */
  59. ao2_unlock(user);
  60. return 0;
  61. }
  62. ao2_unlock(user);
  63. return CMP_MATCH;
  64. }
  65. static enum ast_device_state metermaidstate(const char *data)
  66. {
  67. struct ao2_container *global_lots = get_parking_lot_container();
  68. RAII_VAR(struct parking_lot *, lot, NULL, ao2_cleanup);
  69. char *context;
  70. char *exten;
  71. struct parking_lot_extension_inuse_search search = {};
  72. context = ast_strdupa(data);
  73. exten = strsep(&context, "@");
  74. if (ast_strlen_zero(context) || ast_strlen_zero(exten)) {
  75. return AST_DEVICE_INVALID;
  76. }
  77. search.context = context;
  78. if (sscanf(exten, "%d", &search.exten) != 1) {
  79. return AST_DEVICE_INVALID;
  80. }
  81. ast_debug(4, "Checking state of exten %d in context %s\n", search.exten, context);
  82. lot = ao2_callback(global_lots, 0, parking_lot_search_context_extension_inuse, &data);
  83. if (!lot) {
  84. return AST_DEVICE_NOT_INUSE;
  85. }
  86. return AST_DEVICE_INUSE;
  87. }
  88. void parking_notify_metermaids(int exten, const char *context, enum ast_device_state state)
  89. {
  90. ast_debug(4, "Notification of state change to metermaids %d@%s\n to state '%s'\n",
  91. exten, context, ast_devstate2str(state));
  92. ast_devstate_changed(state, AST_DEVSTATE_CACHABLE, "park:%d@%s", exten, context);
  93. }
  94. void unload_parking_devstate(void)
  95. {
  96. ast_devstate_prov_del("Park");
  97. }
  98. int load_parking_devstate(void)
  99. {
  100. return ast_devstate_prov_add("Park", metermaidstate);
  101. }