app_osplookup.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*
  2. * Asterisk -- A telephony toolkit for Linux.
  3. *
  4. * Time of day - Report the time of day
  5. *
  6. * Copyright (C) 1999, Mark Spencer
  7. *
  8. * Mark Spencer <markster@linux-support.net>
  9. *
  10. * This program is free software, distributed under the terms of
  11. * the GNU General Public License
  12. */
  13. #include <asterisk/lock.h>
  14. #include <asterisk/file.h>
  15. #include <asterisk/logger.h>
  16. #include <asterisk/channel.h>
  17. #include <asterisk/pbx.h>
  18. #include <asterisk/options.h>
  19. #include <asterisk/config.h>
  20. #include <asterisk/module.h>
  21. #include <asterisk/utils.h>
  22. #include <asterisk/causes.h>
  23. #include <asterisk/astosp.h>
  24. #include <stdlib.h>
  25. #include <unistd.h>
  26. #include <string.h>
  27. #include <stdlib.h>
  28. #include <ctype.h>
  29. static char *tdesc = "OSP Lookup";
  30. static char *app = "OSPLookup";
  31. static char *app2 = "OSPNext";
  32. static char *app3 = "OSPFinish";
  33. static char *synopsis = "Lookup number in OSP";
  34. static char *synopsis2 = "Lookup next OSP entry";
  35. static char *synopsis3 = "Record OSP entry";
  36. static char *descrip =
  37. " OSPLookup(exten[|provider[|options]]): Looks up an extension via OSP and sets\n"
  38. "the variables, where 'n' is the number of the result beginning with 1:\n"
  39. " ${OSPTECH}: The technology to use for the call\n"
  40. " ${OSPDEST}: The destination to use for the call\n"
  41. " ${OSPTOKEN}: The actual OSP token as a string\n"
  42. " ${OSPHANDLE}: The OSP Handle for anything remaining\n"
  43. " ${OSPRESULTS}: The number of OSP results total remaining\n"
  44. "\n"
  45. "If the lookup was *not* successful and there exists a priority n + 101,\n"
  46. "then that priority will be taken next.\n" ;
  47. static char *descrip2 =
  48. " OSPNext: Looks up the next OSP Destination for ${OSPHANDLE}\n"
  49. "See OSPLookup for more information\n"
  50. "\n"
  51. "If the lookup was *not* successful and there exists a priority n + 101,\n"
  52. "then that priority will be taken next.\n" ;
  53. static char *descrip3 =
  54. " OSPFinish(status): Records call state for ${OSPHANDLE}, according to\n"
  55. "status, which should be one of BUSY, CONGESTION, ANSWER, NOANSWER, or NOCHANAVAIL\n"
  56. "or coincidentally, just what the Dial application stores in its ${DIALSTATUS}\n"
  57. "\n"
  58. "If the finishing was *not* successful and there exists a priority n + 101,\n"
  59. "then that priority will be taken next.\n" ;
  60. STANDARD_LOCAL_USER;
  61. LOCAL_USER_DECL;
  62. static int str2cause(char *cause)
  63. {
  64. if (!strcasecmp(cause, "BUSY"))
  65. return AST_CAUSE_BUSY;
  66. if (!strcasecmp(cause, "CONGESTION"))
  67. return AST_CAUSE_CONGESTION;
  68. if (!strcasecmp(cause, "ANSWER"))
  69. return AST_CAUSE_NORMAL;
  70. if (!strcasecmp(cause, "CANCEL"))
  71. return AST_CAUSE_NORMAL;
  72. if (!strcasecmp(cause, "NOANSWER"))
  73. return AST_CAUSE_NOANSWER;
  74. if (!strcasecmp(cause, "NOCHANAVAIL"))
  75. return AST_CAUSE_CONGESTION;
  76. ast_log(LOG_WARNING, "Unknown cause '%s', using NORMAL\n", cause);
  77. return AST_CAUSE_NORMAL;
  78. }
  79. static int osplookup_exec(struct ast_channel *chan, void *data)
  80. {
  81. int res=0;
  82. struct localuser *u;
  83. char *temp;
  84. char *provider, *opts=NULL;
  85. struct ast_osp_result result;
  86. if (!data || ast_strlen_zero(data) || !(temp = ast_strdupa(data))) {
  87. ast_log(LOG_WARNING, "OSPLookup requires an argument (extension)\n");
  88. return -1;
  89. }
  90. provider = strchr(temp, '|');
  91. if (provider) {
  92. *provider = '\0';
  93. provider++;
  94. opts = strchr(provider, '|');
  95. if (opts) {
  96. *opts = '\0';
  97. opts++;
  98. }
  99. }
  100. LOCAL_USER_ADD(u);
  101. ast_log(LOG_DEBUG, "Whoo hoo, looking up OSP on '%s' via '%s'\n", temp, provider ? provider : "<default>");
  102. if ((res = ast_osp_lookup(chan, provider, temp, chan->callerid, &result)) > 0) {
  103. char tmp[80];
  104. snprintf(tmp, sizeof(tmp), "%d", result.handle);
  105. pbx_builtin_setvar_helper(chan, "OSPHANDLE", tmp);
  106. pbx_builtin_setvar_helper(chan, "OSPTECH", result.tech);
  107. pbx_builtin_setvar_helper(chan, "OSPDEST", result.dest);
  108. pbx_builtin_setvar_helper(chan, "OSPTOKEN", result.token);
  109. snprintf(tmp, sizeof(tmp), "%d", result.numresults);
  110. pbx_builtin_setvar_helper(chan, "OSPRESULTS", tmp);
  111. } else {
  112. if (!res)
  113. ast_log(LOG_NOTICE, "OSP Lookup failed for '%s' (provider '%s')\n", temp, provider ? provider : "<default>");
  114. else
  115. ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Lookup for '%s' (provider '%s')!\n", chan->name, temp, provider ? provider : "<default>" );
  116. }
  117. if (!res) {
  118. /* Look for a "busy" place */
  119. if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
  120. chan->priority += 100;
  121. } else if (res > 0)
  122. res = 0;
  123. LOCAL_USER_REMOVE(u);
  124. return res;
  125. }
  126. static int ospnext_exec(struct ast_channel *chan, void *data)
  127. {
  128. int res=0;
  129. struct localuser *u;
  130. char *temp;
  131. int cause;
  132. struct ast_osp_result result;
  133. if (!data || ast_strlen_zero(data)) {
  134. ast_log(LOG_WARNING, "OSPNext should have an argument (cause)\n");
  135. }
  136. LOCAL_USER_ADD(u);
  137. cause = str2cause((char *)data);
  138. temp = pbx_builtin_getvar_helper(chan, "OSPHANDLE");
  139. result.handle = -1;
  140. if (temp && strlen(temp) && (sscanf(temp, "%i", &result.handle) == 1) && (result.handle > -1)) {
  141. if ((res = ast_osp_next(&result, cause)) > 0) {
  142. char tmp[80];
  143. snprintf(tmp, sizeof(tmp), "%d", result.handle);
  144. pbx_builtin_setvar_helper(chan, "OSPHANDLE", tmp);
  145. pbx_builtin_setvar_helper(chan, "OSPTECH", result.tech);
  146. pbx_builtin_setvar_helper(chan, "OSPDEST", result.dest);
  147. pbx_builtin_setvar_helper(chan, "OSPTOKEN", result.token);
  148. snprintf(tmp, sizeof(tmp), "%d", result.numresults);
  149. pbx_builtin_setvar_helper(chan, "OSPRESULTS", tmp);
  150. }
  151. } else {
  152. if (!res) {
  153. if (result.handle < 0)
  154. ast_log(LOG_NOTICE, "OSP Lookup Next failed for handle '%d'\n", result.handle);
  155. else
  156. ast_log(LOG_DEBUG, "No OSP handle specified\n");
  157. } else
  158. ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Next!\n", chan->name);
  159. }
  160. if (!res) {
  161. /* Look for a "busy" place */
  162. if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
  163. chan->priority += 100;
  164. } else if (res > 0)
  165. res = 0;
  166. LOCAL_USER_REMOVE(u);
  167. return res;
  168. }
  169. static int ospfinished_exec(struct ast_channel *chan, void *data)
  170. {
  171. int res=0;
  172. struct localuser *u;
  173. char *temp;
  174. int cause;
  175. time_t start=0, duration=0;
  176. struct ast_osp_result result;
  177. if (!data || ast_strlen_zero(data)) {
  178. ast_log(LOG_WARNING, "OSPFinish should have an argument (cause)\n");
  179. }
  180. if (chan->cdr) {
  181. start = chan->cdr->answer.tv_sec;
  182. if (start)
  183. duration = time(NULL) - start;
  184. else
  185. duration = 0;
  186. } else
  187. ast_log(LOG_WARNING, "OSPFinish called on channel '%s' with no CDR!\n", chan->name);
  188. LOCAL_USER_ADD(u);
  189. cause = str2cause((char *)data);
  190. temp = pbx_builtin_getvar_helper(chan, "OSPHANDLE");
  191. result.handle = -1;
  192. if (temp && strlen(temp) && (sscanf(temp, "%i", &result.handle) == 1) && (result.handle > -1)) {
  193. if (!ast_osp_terminate(result.handle, cause, start, duration)) {
  194. pbx_builtin_setvar_helper(chan, "OSPHANDLE", "");
  195. res = 1;
  196. }
  197. } else {
  198. if (!res) {
  199. if (result.handle > -1)
  200. ast_log(LOG_NOTICE, "OSP Finish failed for handle '%d'\n", result.handle);
  201. else
  202. ast_log(LOG_DEBUG, "No OSP handle specified\n");
  203. } else
  204. ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Terminate!\n", chan->name);
  205. }
  206. if (!res) {
  207. /* Look for a "busy" place */
  208. if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
  209. chan->priority += 100;
  210. } else if (res > 0)
  211. res = 0;
  212. LOCAL_USER_REMOVE(u);
  213. return res;
  214. }
  215. int unload_module(void)
  216. {
  217. int res;
  218. STANDARD_HANGUP_LOCALUSERS;
  219. res = ast_unregister_application(app3);
  220. res |= ast_unregister_application(app2);
  221. res |= ast_unregister_application(app);
  222. return res;
  223. }
  224. int load_module(void)
  225. {
  226. int res;
  227. res = ast_register_application(app, osplookup_exec, synopsis, descrip);
  228. if (res)
  229. return(res);
  230. res = ast_register_application(app2, ospnext_exec, synopsis2, descrip2);
  231. if (res)
  232. return(res);
  233. res = ast_register_application(app3, ospfinished_exec, synopsis3, descrip3);
  234. if (res)
  235. return(res);
  236. return(0);
  237. }
  238. int reload(void)
  239. {
  240. return 0;
  241. }
  242. char *description(void)
  243. {
  244. return tdesc;
  245. }
  246. int usecount(void)
  247. {
  248. int res;
  249. STANDARD_USECOUNT(res);
  250. return res;
  251. }
  252. char *key()
  253. {
  254. return ASTERISK_GPL_KEY;
  255. }