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