app_chanisavail.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2005, Digium, Inc.
  5. *
  6. * Mark Spencer <markster@digium.com>
  7. * James Golovich <james@gnuinter.net>
  8. *
  9. * See http://www.asterisk.org for more information about
  10. * the Asterisk project. Please do not directly contact
  11. * any of the maintainers of this project for assistance;
  12. * the project provides a web site, mailing lists and IRC
  13. * channels for your use.
  14. *
  15. * This program is free software, distributed under the terms of
  16. * the GNU General Public License Version 2. See the LICENSE file
  17. * at the top of the source tree.
  18. */
  19. /*! \file
  20. * \brief Check if Channel is Available
  21. *
  22. * \ingroup applications
  23. */
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <unistd.h>
  28. #include <errno.h>
  29. #include <sys/ioctl.h>
  30. #include "asterisk.h"
  31. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  32. #include "asterisk/lock.h"
  33. #include "asterisk/file.h"
  34. #include "asterisk/logger.h"
  35. #include "asterisk/channel.h"
  36. #include "asterisk/pbx.h"
  37. #include "asterisk/module.h"
  38. #include "asterisk/app.h"
  39. #include "asterisk/devicestate.h"
  40. #include "asterisk/options.h"
  41. static char *tdesc = "Check channel availability";
  42. static char *app = "ChanIsAvail";
  43. static char *synopsis = "Check channel availability";
  44. static char *descrip =
  45. " ChanIsAvail(Technology/resource[&Technology2/resource2...][|options]): \n"
  46. "This application will check to see if any of the specified channels are\n"
  47. "available. The following variables will be set by this application:\n"
  48. " ${AVAILCHAN} - the name of the available channel, if one exists\n"
  49. " ${AVAILORIGCHAN} - the canonical channel name that was used to create the channel\n"
  50. " ${AVAILSTATUS} - the status code for the available channel\n"
  51. " Options:\n"
  52. " s - Consider the channel unavailable if the channel is in use at all\n"
  53. " j - Support jumping to priority n+101 if no channel is available\n";
  54. STANDARD_LOCAL_USER;
  55. LOCAL_USER_DECL;
  56. static int chanavail_exec(struct ast_channel *chan, void *data)
  57. {
  58. int res=-1, inuse=-1, option_state=0, priority_jump=0;
  59. int status;
  60. struct localuser *u;
  61. char *info, tmp[512], trychan[512], *peers, *tech, *number, *rest, *cur, *options, *stringp;
  62. struct ast_channel *tempchan;
  63. if (ast_strlen_zero(data)) {
  64. ast_log(LOG_WARNING, "ChanIsAvail requires an argument (Zap/1&Zap/2)\n");
  65. return -1;
  66. }
  67. LOCAL_USER_ADD(u);
  68. info = ast_strdupa(data);
  69. stringp = info;
  70. strsep(&stringp, "|");
  71. options = strsep(&stringp, "|");
  72. if (options) {
  73. if (strchr(options, 's'))
  74. option_state = 1;
  75. if (strchr(options, 'j'))
  76. priority_jump = 1;
  77. }
  78. peers = info;
  79. if (peers) {
  80. cur = peers;
  81. do {
  82. /* remember where to start next time */
  83. rest = strchr(cur, '&');
  84. if (rest) {
  85. *rest = 0;
  86. rest++;
  87. }
  88. tech = cur;
  89. number = strchr(tech, '/');
  90. if (!number) {
  91. ast_log(LOG_WARNING, "ChanIsAvail argument takes format ([technology]/[device])\n");
  92. LOCAL_USER_REMOVE(u);
  93. return -1;
  94. }
  95. *number = '\0';
  96. number++;
  97. if (option_state) {
  98. /* If the pbx says in use then don't bother trying further.
  99. This is to permit testing if someone's on a call, even if the
  100. channel can permit more calls (ie callwaiting, sip calls, etc). */
  101. snprintf(trychan, sizeof(trychan), "%s/%s",cur,number);
  102. status = inuse = ast_device_state(trychan);
  103. }
  104. if ((inuse <= 1) && (tempchan = ast_request(tech, chan->nativeformats, number, &status))) {
  105. pbx_builtin_setvar_helper(chan, "AVAILCHAN", tempchan->name);
  106. /* Store the originally used channel too */
  107. snprintf(tmp, sizeof(tmp), "%s/%s", tech, number);
  108. pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", tmp);
  109. snprintf(tmp, sizeof(tmp), "%d", status);
  110. pbx_builtin_setvar_helper(chan, "AVAILSTATUS", tmp);
  111. ast_hangup(tempchan);
  112. tempchan = NULL;
  113. res = 1;
  114. break;
  115. } else {
  116. snprintf(tmp, sizeof(tmp), "%d", status);
  117. pbx_builtin_setvar_helper(chan, "AVAILSTATUS", tmp);
  118. }
  119. cur = rest;
  120. } while (cur);
  121. }
  122. if (res < 1) {
  123. pbx_builtin_setvar_helper(chan, "AVAILCHAN", "");
  124. pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", "");
  125. if (priority_jump || option_priority_jumping) {
  126. if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) {
  127. LOCAL_USER_REMOVE(u);
  128. return -1;
  129. }
  130. }
  131. }
  132. LOCAL_USER_REMOVE(u);
  133. return 0;
  134. }
  135. int unload_module(void)
  136. {
  137. int res = 0;
  138. res = ast_unregister_application(app);
  139. STANDARD_HANGUP_LOCALUSERS;
  140. return res;
  141. }
  142. int load_module(void)
  143. {
  144. return ast_register_application(app, chanavail_exec, synopsis, descrip);
  145. }
  146. char *description(void)
  147. {
  148. return tdesc;
  149. }
  150. int usecount(void)
  151. {
  152. int res;
  153. STANDARD_USECOUNT(res);
  154. return res;
  155. }
  156. char *key()
  157. {
  158. return ASTERISK_GPL_KEY;
  159. }