00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "asterisk.h"
00014
00015 #include <stdlib.h>
00016 #include <unistd.h>
00017 #include <string.h>
00018 #include <stdio.h>
00019
00020 #include "asterisk/lock.h"
00021 #include "asterisk/file.h"
00022 #include "asterisk/logger.h"
00023 #include "asterisk/channel.h"
00024 #include "asterisk/pbx.h"
00025 #include "asterisk/astdb.h"
00026 #include "asterisk/cli.h"
00027 #include "asterisk/manager.h"
00028 #include "asterisk/devicestate.h"
00029 #include "asterisk/module.h"
00030
00031
00032 static char type[] = "DS";
00033 static char tdesc[] = "Application for sending device state messages";
00034
00035 static char app[] = "Devstate";
00036
00037 static char synopsis[] = "Generate a device state change event given the input parameters";
00038
00039 static char descrip[] = " Devstate(device|state): Generate a device state change event given the input parameters. Returns 0. State values match the asterisk device states. They are 0 = unknown, 1 = not inuse, 2 = inuse, 3 = busy, 4 = invalid, 5 = unavailable, 6 = ringing\n";
00040
00041 static char devstate_cli_usage[] =
00042 "Usage: devstate device state\n"
00043 " Generate a device state change event given the input parameters.\n Mainly used for lighting the LEDs on the snoms.\n";
00044
00045 static int devstate_cli(int fd, int argc, char *argv[]);
00046 static struct ast_cli_entry cli_dev_state =
00047 { { "devstate", NULL }, devstate_cli, "Set the device state on one of the \"pseudo devices\".", devstate_cli_usage };
00048
00049
00050 static int devstate_cli(int fd, int argc, char *argv[])
00051 {
00052 char devName[128];
00053 if ((argc != 3) && (argc != 4) && (argc != 5))
00054 return RESULT_SHOWUSAGE;
00055
00056 if (ast_db_put("DEVSTATES", argv[1], argv[2]))
00057 {
00058 ast_log(LOG_DEBUG, "ast_db_put failed\n");
00059 }
00060 snprintf(devName, sizeof(devName), "DS/%s", argv[1]);
00061 if (argc == 4) {
00062 ast_log(LOG_NOTICE, "devname %s cid %s\n", devName, argv[3]);
00063 ast_device_state_changed_literal(devName, argv[3], NULL);
00064 } else if (argc == 5) {
00065 ast_log(LOG_NOTICE, "devname %s cid %s cidname %s\n", devName, argv[3], argv[4]);
00066 ast_device_state_changed_literal(devName, argv[3], argv[4]);
00067 } else {
00068 ast_device_state_changed_literal(devName, NULL, NULL);
00069 }
00070 return RESULT_SUCCESS;
00071 }
00072
00073 static int devstate_exec(struct ast_channel *chan, void *data)
00074 {
00075 char *device, *state, *info;
00076 char devName[128];
00077 struct ast_module_user *u;
00078
00079
00080 if (!(info = ast_strdupa(data))) {
00081 ast_log(LOG_WARNING, "Unable to dupe data :(\n");
00082 return -1;
00083 }
00084
00085 u = ast_module_user_add(chan);
00086 device = info;
00087 state = strchr(info, '|');
00088 if (state) {
00089 *state = '\0';
00090 state++;
00091 }
00092 else
00093 {
00094 ast_log(LOG_DEBUG, "No state argument supplied\n");
00095 return -1;
00096 }
00097
00098 if (ast_db_put("DEVSTATES", device, state))
00099 {
00100 ast_log(LOG_DEBUG, "ast_db_put failed\n");
00101 }
00102
00103 snprintf(devName, sizeof(devName), "DS/%s", device);
00104 ast_device_state_changed_literal(devName, NULL, NULL);
00105
00106 ast_module_user_remove(u);
00107 return 0;
00108 }
00109
00110
00111 static int ds_devicestate(void *data)
00112 {
00113 char *dest = data;
00114 char stateStr[16];
00115 if (ast_db_get("DEVSTATES", dest, stateStr, sizeof(stateStr)))
00116 {
00117 ast_log(LOG_DEBUG, "ds_devicestate couldnt get state in astdb\n");
00118 return 0;
00119 }
00120 else
00121 {
00122 ast_log(LOG_DEBUG, "ds_devicestate dev=%s returning state %d\n",
00123 dest, atoi(stateStr));
00124 return (atoi(stateStr));
00125 }
00126 }
00127
00128 static struct ast_channel_tech devstate_tech = {
00129 .type = type,
00130 .description = tdesc,
00131 .capabilities = ((AST_FORMAT_MAX_AUDIO << 1) - 1),
00132 .devicestate = ds_devicestate,
00133 .requester = NULL,
00134 .send_digit_begin = NULL,
00135 .send_digit_end = NULL,
00136 .send_text = NULL,
00137 .call = NULL,
00138 .hangup = NULL,
00139 .answer = NULL,
00140 .read = NULL,
00141 .write = NULL,
00142 .bridge = NULL,
00143 .exception = NULL,
00144 .indicate = NULL,
00145 .fixup = NULL,
00146 .setoption = NULL,
00147 };
00148
00149 static char mandescr_devstate[] =
00150 "Description: Put a value into astdb\n"
00151 "Variables: \n"
00152 " Family: ...\n"
00153 " Key: ...\n"
00154 " Value: ...\n";
00155
00156 static int action_devstate(struct mansession *s, const struct message *m)
00157 {
00158 const char *devstate = astman_get_header(m, "Devstate");
00159 const char *value = astman_get_header(m, "Value");
00160 const char *id = astman_get_header(m,"ActionID");
00161 const char *cid_num = astman_get_header(m, "CallerID");
00162 const char *cid_name = astman_get_header(m, "CallerIDName");
00163 char devName[128];
00164 char idText[256] = "";
00165
00166 if (!strlen(devstate)) {
00167 astman_send_error(s, m, "No Devstate specified");
00168 return 0;
00169 }
00170 if (!strlen(value)) {
00171 astman_send_error(s, m, "No Value specified");
00172 return 0;
00173 }
00174 if (!ast_strlen_zero(id))
00175 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
00176
00177 if (!ast_db_put("DEVSTATES", devstate, (char *)value)) {
00178 snprintf(devName, sizeof(devName), "DS/%s", devstate);
00179 ast_device_state_changed_literal(devName, cid_num, cid_name);
00180 astman_append(s, "Response: Success\r\n%s\r\n", idText);
00181 } else {
00182 ast_log(LOG_DEBUG, "ast_db_put failed\n");
00183 astman_append(s, "Response: Failed\r\n%s\r\n", idText);
00184 }
00185 return 0;
00186 }
00187
00188 static int load_module(void)
00189 {
00190 if (ast_channel_register(&devstate_tech)) {
00191 ast_log(LOG_DEBUG, "Unable to register channel class %s\n", type);
00192 return -1;
00193 }
00194 ast_cli_register(&cli_dev_state);
00195 ast_manager_register2( "Devstate", EVENT_FLAG_CALL, action_devstate, "Change a device state", mandescr_devstate );
00196 return ast_register_application(app, devstate_exec, synopsis, descrip);
00197 }
00198
00199 static int unload_module(void)
00200 {
00201 int res = 0;
00202
00203 ast_module_user_hangup_all();
00204 ast_manager_unregister( "Devstate");
00205 ast_cli_unregister(&cli_dev_state);
00206 res = ast_unregister_application(app);
00207 ast_channel_unregister(&devstate_tech);
00208 return res;
00209 }
00210
00211 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Simple Devstate Application");
00212