#include <linux/soundcard.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
Include dependency graph for muted.c:
Go to the source code of this file.
Functions | |
static void | add_channel (char *tech, char *location) |
static void | append_sub (struct channel *chan, char *name) |
static void | check_mute (void) |
static int | connect_asterisk (void) |
static void | delete_sub (struct channel *chan, char *name) |
static struct channel * | find_channel (char *channel) |
static char * | get_line (void) |
static int | getvol (void) |
static void | hangup_chan (char *channel) |
static int | load_config (void) |
static int | login_asterisk (void) |
int | main (int argc, char *argv[]) |
static void | mute (void) |
static int | mutedlevel (int orig, int mutelevel) |
static void | offhook_chan (char *channel) |
static int | open_mixer (void) |
static int | setvol (int vol) |
static void | unmute (void) |
static void | usage (void) |
static int | wait_event (void) |
Variables | |
static FILE * | astf |
static struct channel * | channels |
static char * | config = "/etc/muted.conf" |
static int | debug = 0 |
static char | host [256] = "" |
static int | mixchan = SOUND_MIXER_VOLUME |
static int | mixfd |
static int | muted = 0 |
static int | mutelevel = 20 |
static int | mutevol = 0 |
static int | needfork = 1 |
static int | oldvol = 0 |
static char | pass [256] = "" |
static int | smoothfade = 0 |
static int | stepsize = 3 |
static char | user [256] = "" |
Definition in file muted.c.
|
Definition at line 76 of file muted.c. References channels, malloc, and strdup. Referenced by load_config(). 00077 { 00078 struct channel *chan; 00079 chan = malloc(sizeof(struct channel)); 00080 if (chan) { 00081 memset(chan, 0, sizeof(struct channel)); 00082 chan->tech = strdup(tech); 00083 chan->location = strdup(location); 00084 chan->next = channels; 00085 channels = chan; 00086 } 00087 00088 }
|
|
Definition at line 535 of file muted.c. References malloc, subchannel::name, subchannel::next, strdup, and channel::subs. Referenced by offhook_chan(). 00536 { 00537 struct subchannel *sub; 00538 sub = chan->subs; 00539 while(sub) { 00540 if (!strcasecmp(sub->name, name)) 00541 return; 00542 sub = sub->next; 00543 } 00544 sub = malloc(sizeof(struct subchannel)); 00545 if (sub) { 00546 memset(sub, 0, sizeof(struct subchannel)); 00547 sub->name = strdup(name); 00548 sub->next = chan->subs; 00549 chan->subs = sub; 00550 } 00551 }
|
|
Definition at line 497 of file muted.c. References channels, mute(), muted, channel::next, channel::subs, and unmute(). Referenced by hangup_chan(), and offhook_chan(). 00498 { 00499 int offhook = 0; 00500 struct channel *chan; 00501 chan = channels; 00502 while(chan) { 00503 if (chan->subs) { 00504 offhook++; 00505 break; 00506 } 00507 chan = chan->next; 00508 } 00509 if (offhook && !muted) 00510 mute(); 00511 else if (!offhook && muted) 00512 unmute(); 00513 }
|
|
Connect to the asterisk manager interface Definition at line 190 of file muted.c. References astf, gethostbyname, host, and hp. Referenced by main(). 00191 { 00192 int sock; 00193 struct hostent *hp; 00194 char *ports; 00195 int port = 5038; 00196 struct sockaddr_in sin; 00197 00198 ports = strchr(host, ':'); 00199 if (ports) { 00200 *ports = '\0'; 00201 ports++; 00202 if ((sscanf(ports, "%d", &port) != 1) || (port < 1) || (port > 65535)) { 00203 fprintf(stderr, "'%s' is not a valid port number in the hostname\n", ports); 00204 return -1; 00205 } 00206 } 00207 hp = gethostbyname(host); 00208 if (!hp) { 00209 fprintf(stderr, "Can't find host '%s'\n", host); 00210 return -1; 00211 } 00212 sock = socket(AF_INET, SOCK_STREAM, 0); 00213 if (sock < 0) { 00214 fprintf(stderr, "Failed to create socket: %s\n", strerror(errno)); 00215 return -1; 00216 } 00217 sin.sin_family = AF_INET; 00218 sin.sin_port = htons(port); 00219 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 00220 if (connect(sock, &sin, sizeof(sin))) { 00221 fprintf(stderr, "Failed to connect to '%s' port '%d': %s\n", host, port, strerror(errno)); 00222 close(sock); 00223 return -1; 00224 } 00225 astf = fdopen(sock, "r+"); 00226 if (!astf) { 00227 fprintf(stderr, "fdopen failed: %s\n", strerror(errno)); 00228 close(sock); 00229 return -1; 00230 } 00231 return 0; 00232 }
|
|
Definition at line 515 of file muted.c. References free, subchannel::name, subchannel::next, and channel::subs. Referenced by hangup_chan(). 00516 { 00517 struct subchannel *sub, *prev; 00518 prev = NULL; 00519 sub = chan->subs; 00520 while(sub) { 00521 if (!strcasecmp(sub->name, name)) { 00522 if (prev) 00523 prev->next = sub->next; 00524 else 00525 chan->subs = sub->next; 00526 free(sub->name); 00527 free(sub); 00528 return; 00529 } 00530 prev = sub; 00531 sub = sub->next; 00532 } 00533 }
|
|
Definition at line 291 of file muted.c. References channels, debug, channel::location, channel::next, s, t, and channel::tech. Referenced by action_transfer(), action_transferhangup(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), hangup_chan(), and offhook_chan(). 00292 { 00293 char tmp[256] = ""; 00294 char *s, *t; 00295 struct channel *chan; 00296 strncpy(tmp, channel, sizeof(tmp) - 1); 00297 s = strchr(tmp, '/'); 00298 if (s) { 00299 *s = '\0'; 00300 s++; 00301 t = strrchr(s, '-'); 00302 if (t) { 00303 *t = '\0'; 00304 } 00305 if (debug) 00306 printf("Searching for '%s' tech, '%s' location\n", tmp, s); 00307 chan = channels; 00308 while(chan) { 00309 if (!strcasecmp(chan->tech, tmp) && !strcasecmp(chan->location, s)) { 00310 if (debug) 00311 printf("Found '%s'/'%s'\n", chan->tech, chan->location); 00312 break; 00313 } 00314 chan = chan->next; 00315 } 00316 } else 00317 chan = NULL; 00318 return chan; 00319 }
|
|
Definition at line 234 of file muted.c. References astf. Referenced by login_asterisk(), and wait_event(). 00235 { 00236 static char buf[1024]; 00237 if (fgets(buf, sizeof(buf), astf)) { 00238 while(strlen(buf) && (buf[strlen(buf) - 1] < 33)) 00239 buf[strlen(buf) - 1] = '\0'; 00240 return buf; 00241 } else 00242 return NULL; 00243 }
|
|
Definition at line 322 of file muted.c. References channels, mixchan, and mixfd. Referenced by mute(), and unmute(). 00323 { 00324 int vol; 00325 00326 if (ioctl(mixfd, MIXER_READ(mixchan), &vol)) { 00327 #else 00328 static float getvol(void) 00329 { 00330 float volumeL, volumeR, vol; 00331 OSStatus err; 00332 AudioDeviceID device; 00333 UInt32 size; 00334 UInt32 channels[2]; 00335 00336 size = sizeof(device); 00337 err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &size, &device); 00338 size = sizeof(channels); 00339 if (!err) 00340 err = AudioDeviceGetProperty(device, 0, false, kAudioDevicePropertyPreferredChannelsForStereo, &size, &channels); 00341 size = sizeof(vol); 00342 if (!err) 00343 err = AudioDeviceGetProperty(device, channels[0], false, kAudioDevicePropertyVolumeScalar, &size, &volumeL); 00344 if (!err) 00345 err = AudioDeviceGetProperty(device, channels[1], false, kAudioDevicePropertyVolumeScalar, &size, &volumeR); 00346 if (!err) 00347 vol = (volumeL < volumeR) ? volumeR : volumeL; 00348 else { 00349 #endif 00350 fprintf(stderr, "Unable to read mixer volume: %s\n", strerror(errno)); 00351 return -1; 00352 } 00353 return vol; 00354 }
|
|
Definition at line 553 of file muted.c. References check_mute(), debug, delete_sub(), and find_channel(). Referenced by wait_event(). 00554 { 00555 struct channel *chan; 00556 if (debug) 00557 printf("Hangup '%s'\n", channel); 00558 chan = find_channel(channel); 00559 if (chan) 00560 delete_sub(chan, channel); 00561 check_mute(); 00562 }
|
|
Definition at line 90 of file muted.c. References add_channel(), channels, config, host, mutelevel, pass, smoothfade, and user. Referenced by load_module(), main(), and reload(). 00091 { 00092 FILE *f; 00093 char buf[1024]; 00094 char *val; 00095 char *val2; 00096 int lineno=0; 00097 int x; 00098 f = fopen(config, "r"); 00099 if (!f) { 00100 fprintf(stderr, "Unable to open config file '%s': %s\n", config, strerror(errno)); 00101 return -1; 00102 } 00103 while(!feof(f)) { 00104 fgets(buf, sizeof(buf), f); 00105 if (!feof(f)) { 00106 lineno++; 00107 val = strchr(buf, '#'); 00108 if (val) *val = '\0'; 00109 while(strlen(buf) && (buf[strlen(buf) - 1] < 33)) 00110 buf[strlen(buf) - 1] = '\0'; 00111 if (!strlen(buf)) 00112 continue; 00113 val = buf; 00114 while(*val) { 00115 if (*val < 33) 00116 break; 00117 val++; 00118 } 00119 if (*val) { 00120 *val = '\0'; 00121 val++; 00122 while(*val && (*val < 33)) val++; 00123 } 00124 if (!strcasecmp(buf, "host")) { 00125 if (val && strlen(val)) 00126 strncpy(host, val, sizeof(host) - 1); 00127 else 00128 fprintf(stderr, "host needs an argument (the host) at line %d\n", lineno); 00129 } else if (!strcasecmp(buf, "user")) { 00130 if (val && strlen(val)) 00131 strncpy(user, val, sizeof(user) - 1); 00132 else 00133 fprintf(stderr, "user needs an argument (the user) at line %d\n", lineno); 00134 } else if (!strcasecmp(buf, "pass")) { 00135 if (val && strlen(val)) 00136 strncpy(pass, val, sizeof(pass) - 1); 00137 else 00138 fprintf(stderr, "pass needs an argument (the password) at line %d\n", lineno); 00139 } else if (!strcasecmp(buf, "smoothfade")) { 00140 smoothfade = 1; 00141 } else if (!strcasecmp(buf, "mutelevel")) { 00142 if (val && (sscanf(val, "%d", &x) == 1) && (x > -1) && (x < 101)) { 00143 mutelevel = x; 00144 } else 00145 fprintf(stderr, "mutelevel must be a number from 0 (most muted) to 100 (no mute) at line %d\n", lineno); 00146 } else if (!strcasecmp(buf, "channel")) { 00147 if (val && strlen(val)) { 00148 val2 = strchr(val, '/'); 00149 if (val2) { 00150 *val2 = '\0'; 00151 val2++; 00152 add_channel(val, val2); 00153 } else 00154 fprintf(stderr, "channel needs to be of the format Tech/Location at line %d\n", lineno); 00155 } else 00156 fprintf(stderr, "channel needs an argument (the channel) at line %d\n", lineno); 00157 } else { 00158 fprintf(stderr, "ignoring unknown keyword '%s'\n", buf); 00159 } 00160 } 00161 } 00162 fclose(f); 00163 if (!strlen(host)) 00164 fprintf(stderr, "no 'host' specification in config file\n"); 00165 else if (!strlen(user)) 00166 fprintf(stderr, "no 'user' specification in config file\n"); 00167 else if (!channels) 00168 fprintf(stderr, "no 'channel' specifications in config file\n"); 00169 else 00170 return 0; 00171 return -1; 00172 }
|
|
Login to the asterisk manager interface Definition at line 246 of file muted.c. References astf, get_line(), pass, and user. Referenced by main(). 00247 { 00248 char *welcome; 00249 char *resp; 00250 if (!(welcome = get_line())) { 00251 fprintf(stderr, "disconnected (1)\n"); 00252 return -1; 00253 } 00254 fprintf(astf, 00255 "Action: Login\r\n" 00256 "Username: %s\r\n" 00257 "Secret: %s\r\n\r\n", user, pass); 00258 if (!(welcome = get_line())) { 00259 fprintf(stderr, "disconnected (2)\n"); 00260 return -1; 00261 } 00262 if (strcasecmp(welcome, "Response: Success")) { 00263 fprintf(stderr, "login failed ('%s')\n", welcome); 00264 return -1; 00265 } 00266 /* Eat the rest of the event */ 00267 while((resp = get_line()) && strlen(resp)); 00268 if (!resp) { 00269 fprintf(stderr, "disconnected (3)\n"); 00270 return -1; 00271 } 00272 fprintf(astf, 00273 "Action: Status\r\n\r\n"); 00274 if (!(welcome = get_line())) { 00275 fprintf(stderr, "disconnected (4)\n"); 00276 return -1; 00277 } 00278 if (strcasecmp(welcome, "Response: Success")) { 00279 fprintf(stderr, "status failed ('%s')\n", welcome); 00280 return -1; 00281 } 00282 /* Eat the rest of the event */ 00283 while((resp = get_line()) && strlen(resp)); 00284 if (!resp) { 00285 fprintf(stderr, "disconnected (5)\n"); 00286 return -1; 00287 } 00288 return 0; 00289 }
|
|
Definition at line 629 of file muted.c. References astf, connect_asterisk(), debug, load_config(), login_asterisk(), mixfd, needfork, open_mixer(), usage(), and wait_event(). 00630 { 00631 int x; 00632 while((x = getopt(argc, argv, "fhd")) > 0) { 00633 switch(x) { 00634 case 'd': 00635 debug = 1; 00636 needfork = 0; 00637 break; 00638 case 'f': 00639 needfork = 0; 00640 break; 00641 case 'h': 00642 /* Fall through */ 00643 default: 00644 usage(); 00645 exit(1); 00646 } 00647 } 00648 if (load_config()) 00649 exit(1); 00650 #ifndef __Darwin__ 00651 if (open_mixer()) 00652 exit(1); 00653 #endif 00654 if (connect_asterisk()) { 00655 #ifndef __Darwin__ 00656 close(mixfd); 00657 #endif 00658 exit(1); 00659 } 00660 if (login_asterisk()) { 00661 #ifndef __Darwin__ 00662 close(mixfd); 00663 #endif 00664 fclose(astf); 00665 exit(1); 00666 } 00667 if (needfork) 00668 daemon(0,0); 00669 for(;;) { 00670 if (wait_event()) { 00671 fclose(astf); 00672 while(connect_asterisk()) { 00673 sleep(5); 00674 } 00675 if (login_asterisk()) { 00676 fclose(astf); 00677 exit(1); 00678 } 00679 } 00680 } 00681 exit(0); 00682 }
|
|
Definition at line 418 of file muted.c. References debug, getvol(), muted, mutedlevel(), setvol(), smoothfade, and stepsize. Referenced by check_mute(). 00419 { 00420 #ifndef __Darwin__ 00421 int vol; 00422 int start; 00423 int x; 00424 #else 00425 float vol; 00426 float start = 1.0; 00427 float x; 00428 #endif 00429 vol = getvol(); 00430 oldvol = vol; 00431 if (smoothfade) 00432 #ifdef __Darwin__ 00433 start = mutelevel; 00434 #else 00435 start = 100; 00436 else 00437 start = mutelevel; 00438 #endif 00439 for (x=start;x>=mutelevel;x-=stepsize) { 00440 mutevol = mutedlevel(vol, x); 00441 setvol(mutevol); 00442 /* Wait 0.01 sec */ 00443 usleep(10000); 00444 } 00445 mutevol = mutedlevel(vol, mutelevel); 00446 setvol(mutevol); 00447 if (debug) 00448 #ifdef __Darwin__ 00449 printf("Mute from '%f' to '%f'!\n", oldvol, mutevol); 00450 #else 00451 printf("Mute from '%04x' to '%04x'!\n", oldvol, mutevol); 00452 #endif 00453 muted = 1; 00454 }
|
|
Definition at line 400 of file muted.c. References master. Referenced by mute(), and unmute(). 00401 { 00402 int l = orig >> 8; 00403 int r = orig & 0xff; 00404 l = (float)(mutelevel) * (float)(l) / 100.0; 00405 r = (float)(mutelevel) * (float)(r) / 100.0; 00406 00407 return (l << 8) | r; 00408 #else 00409 static float mutedlevel(float orig, float mutelevel) 00410 { 00411 float master = orig; 00412 master = mutelevel * master / 100.0; 00413 return master; 00414 #endif 00415 00416 }
|
|
Definition at line 564 of file muted.c. References append_sub(), check_mute(), debug, and find_channel(). Referenced by wait_event(). 00565 { 00566 struct channel *chan; 00567 if (debug) 00568 printf("Offhook '%s'\n", channel); 00569 chan = find_channel(channel); 00570 if (chan) 00571 append_sub(chan, channel); 00572 check_mute(); 00573 }
|
|
Definition at line 178 of file muted.c. References mixfd. Referenced by main(). 00179 { 00180 mixfd = open("/dev/mixer", O_RDWR); 00181 if (mixfd < 0) { 00182 fprintf(stderr, "Unable to open /dev/mixer: %s\n", strerror(errno)); 00183 return -1; 00184 } 00185 return 0; 00186 }
|
|
Definition at line 357 of file muted.c. References channels, mixchan, and mixfd. Referenced by mute(), and unmute(). 00361 { 00362 #ifndef __Darwin__ 00363 if (ioctl(mixfd, MIXER_WRITE(mixchan), &vol)) { 00364 #else 00365 float volumeL = vol; 00366 float volumeR = vol; 00367 OSStatus err; 00368 AudioDeviceID device; 00369 UInt32 size; 00370 UInt32 channels[2]; 00371 00372 size = sizeof(device); 00373 err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &size, &device); 00374 size = sizeof(channels); 00375 err = AudioDeviceGetProperty(device, 0, false, kAudioDevicePropertyPreferredChannelsForStereo, &size, &channels); 00376 size = sizeof(vol); 00377 if (!err) 00378 err = AudioDeviceSetProperty(device, 0, channels[0], false, kAudioDevicePropertyVolumeScalar, size, &volumeL); 00379 if (!err) 00380 err = AudioDeviceSetProperty(device, 0, channels[1], false, kAudioDevicePropertyVolumeScalar, size, &volumeR); 00381 if (err) { 00382 #endif 00383 00384 fprintf(stderr, "Unable to write mixer volume: %s\n", strerror(errno)); 00385 return -1; 00386 00387 } 00388 return 0; 00389 }
|
|
Definition at line 456 of file muted.c. References debug, getvol(), muted, mutedlevel(), setvol(), smoothfade, and stepsize. Referenced by check_mute(). 00457 { 00458 #ifdef __Darwin__ 00459 float vol; 00460 float start; 00461 float x; 00462 #else 00463 int vol; 00464 int start; 00465 int x; 00466 #endif 00467 vol = getvol(); 00468 if (debug) 00469 #ifdef __Darwin__ 00470 printf("Unmute from '%f' (should be '%f') to '%f'!\n", vol, mutevol, oldvol); 00471 mutevol = vol; 00472 if (vol == mutevol) { 00473 #else 00474 printf("Unmute from '%04x' (should be '%04x') to '%04x'!\n", vol, mutevol, oldvol); 00475 if ((int)vol == mutevol) { 00476 #endif 00477 if (smoothfade) 00478 start = mutelevel; 00479 else 00480 #ifdef __Darwin__ 00481 start = 1.0; 00482 #else 00483 start = 100; 00484 #endif 00485 for (x=start;x<100;x+=stepsize) { 00486 mutevol = mutedlevel(oldvol, x); 00487 setvol(mutevol); 00488 /* Wait 0.01 sec */ 00489 usleep(10000); 00490 } 00491 setvol(oldvol); 00492 } else 00493 printf("Whoops, it's already been changed!\n"); 00494 muted = 0; 00495 }
|
|
Definition at line 622 of file muted.c. Referenced by main(), and pbx_builtin_execiftime(). 00623 { 00624 printf("Usage: muted [-f] [-d]\n" 00625 " -f : Do not fork\n" 00626 " -d : Debug (implies -f)\n"); 00627 }
|
|
Definition at line 575 of file muted.c. References get_line(), hangup_chan(), and offhook_chan(). Referenced by main(). 00576 { 00577 char *resp; 00578 char event[120]=""; 00579 char channel[120]=""; 00580 char oldname[120]=""; 00581 char newname[120]=""; 00582 00583 resp = get_line(); 00584 if (!resp) { 00585 fprintf(stderr, "disconnected (6)\n"); 00586 return -1; 00587 } 00588 if (!strncasecmp(resp, "Event: ", strlen("Event: "))) { 00589 strncpy(event, resp + strlen("Event: "), sizeof(event) - 1); 00590 /* Consume the rest of the non-event */ 00591 while((resp = get_line()) && strlen(resp)) { 00592 if (!strncasecmp(resp, "Channel: ", strlen("Channel: "))) 00593 strncpy(channel, resp + strlen("Channel: "), sizeof(channel) - 1); 00594 if (!strncasecmp(resp, "Newname: ", strlen("Newname: "))) 00595 strncpy(newname, resp + strlen("Newname: "), sizeof(newname) - 1); 00596 if (!strncasecmp(resp, "Oldname: ", strlen("Oldname: "))) 00597 strncpy(oldname, resp + strlen("Oldname: "), sizeof(oldname) - 1); 00598 } 00599 if (strlen(channel)) { 00600 if (!strcasecmp(event, "Hangup")) 00601 hangup_chan(channel); 00602 else 00603 offhook_chan(channel); 00604 } 00605 if (strlen(newname) && strlen(oldname)) { 00606 if (!strcasecmp(event, "Rename")) { 00607 hangup_chan(oldname); 00608 offhook_chan(newname); 00609 } 00610 } 00611 } else { 00612 /* Consume the rest of the non-event */ 00613 while((resp = get_line()) && strlen(resp)); 00614 } 00615 if (!resp) { 00616 fprintf(stderr, "disconnected (7)\n"); 00617 return -1; 00618 } 00619 return 0; 00620 }
|
|
Definition at line 174 of file muted.c. Referenced by connect_asterisk(), get_line(), login_asterisk(), and main(). |
|
|
|
Definition at line 49 of file muted.c. Referenced by agents_show(), ast_config_new(), ast_readconfig(), do_reload(), handle_save_dialplan(), ind_load_module(), load_config(), load_module(), load_odbc_config(), misdn_cfg_init(), my_load_module(), odbc_load_module(), parse_gain_value(), pbx_load_module(), read_agent_config(), read_config_maps(), reload(), reload_config(), setup_zap(), and tds_load_module(). |
|
|
Definition at line 51 of file muted.c. Referenced by ast_get_ip_or_srv(), ast_netsock_bind(), connect_asterisk(), create_addr(), festival_exec(), find_callno(), iax2_request(), iax2_show_registry(), launch_netscript(), load_config(), oh323_request(), process_sdp(), sendmail(), sendpage(), sip_devicestate(), sip_request_call(), sip_show_registry(), and sip_sipredirect(). |
|
|
|
Definition at line 176 of file muted.c. Referenced by getvol(), main(), open_mixer(), and setvol(). |
|
Definition at line 56 of file muted.c. Referenced by check_mute(), mute(), and unmute(). |
|
Definition at line 55 of file muted.c. Referenced by load_config(). |
|
|
|
Definition at line 57 of file muted.c. Referenced by main(). |
|
|
|
Definition at line 53 of file muted.c. Referenced by __ast_dsp_call_progress(), __get_header(), __login_exec(), add_mod(), ast_db_deltree(), ast_db_gettree(), authenticate(), build_transactions(), database_show(), database_showkey(), load_config(), login_asterisk(), and vm_change_password(). |
|
Definition at line 54 of file muted.c. Referenced by load_config(), mute(), and unmute(). |
|
|
|