Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
muted.c File Reference

Mute Daemon. More...

#include "asterisk/autoconfig.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.

Data Structures

struct  channel
 
struct  subchannel
 

Macros

#define ast_strlen_zero(a)   (!(*(a)))
 

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 channelfind_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 level)
 
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 channelchannels
 
static char * config = "/etc/asterisk/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] = ""
 

Detailed Description

Mute Daemon.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Updated for Mac OSX CoreAudio

Note
Specially written for Malcolm Davenport, but I think I'll use it too Connects to the Asterisk Manager Interface, AMI, and listens for events on certain devices. If a phone call is connected to one of the devices (phones) the local sound is muted to a lower volume during the call.

Definition in file muted.c.

Macro Definition Documentation

◆ ast_strlen_zero

#define ast_strlen_zero (   a)    (!(*(a)))

Definition at line 73 of file muted.c.

Function Documentation

◆ add_channel()

static void add_channel ( char *  tech,
char *  location 
)
static

Definition at line 102 of file muted.c.

References channels, free(), channel::location, malloc(), channel::next, strdup, and channel::tech.

Referenced by load_config().

103 {
104  struct channel *chan;
105  chan = malloc(sizeof(struct channel));
106  if (chan) {
107  memset(chan, 0, sizeof(struct channel));
108  if (!(chan->tech = strdup(tech))) {
109  free(chan);
110  return;
111  }
112  if (!(chan->location = strdup(location))) {
113  free(chan->tech);
114  free(chan);
115  return;
116  }
117  chan->next = channels;
118  channels = chan;
119  }
120 
121 }
char * tech
Definition: muted.c:96
Definition: muted.c:95
char * malloc()
void free()
static struct channel * channels
#define strdup(a)
Definition: astmm.h:165
struct channel * next
Definition: muted.c:98
char * location
Definition: muted.c:97

◆ append_sub()

static void append_sub ( struct channel chan,
char *  name 
)
static

Definition at line 585 of file muted.c.

References free(), malloc(), subchannel::name, subchannel::next, strdup, sub, and channel::subs.

Referenced by offhook_chan().

586 {
587  struct subchannel *sub;
588  sub = chan->subs;
589  while(sub) {
590  if (!strcasecmp(sub->name, name))
591  return;
592  sub = sub->next;
593  }
594  sub = malloc(sizeof(struct subchannel));
595  if (sub) {
596  memset(sub, 0, sizeof(struct subchannel));
597  if (!(sub->name = strdup(name))) {
598  free(sub);
599  return;
600  }
601  sub->next = chan->subs;
602  chan->subs = sub;
603  }
604 }
char * malloc()
void free()
static const char name[]
Definition: cdr_mysql.c:74
struct subchannel * subs
Definition: muted.c:99
struct stasis_forward * sub
Definition: res_corosync.c:240
char * name
Definition: muted.c:91
#define strdup(a)
Definition: astmm.h:165
struct subchannel * next
Definition: muted.c:92

◆ check_mute()

static void check_mute ( void  )
static

Definition at line 547 of file muted.c.

References channels, mute(), muted, channel::next, channel::subs, and unmute().

Referenced by hangup_chan(), and offhook_chan().

548 {
549  int offhook = 0;
550  struct channel *chan;
551  chan = channels;
552  while(chan) {
553  if (chan->subs) {
554  offhook++;
555  break;
556  }
557  chan = chan->next;
558  }
559  if (offhook && !muted)
560  mute();
561  else if (!offhook && muted)
562  unmute();
563 }
static int muted
Definition: muted.c:82
Definition: muted.c:95
static void mute(void)
Definition: muted.c:468
static struct channel * channels
static void unmute(void)
Definition: muted.c:506
struct subchannel * subs
Definition: muted.c:99
struct channel * next
Definition: muted.c:98

◆ connect_asterisk()

static int connect_asterisk ( void  )
static

Connect to the asterisk manager interface

Definition at line 225 of file muted.c.

References astf, errno, gethostbyname, host, and hp.

Referenced by main().

226 {
227  int sock;
228  struct hostent *hp;
229  char *ports;
230  int port = 5038;
231  struct sockaddr_in sin;
232 
233  ports = strchr(host, ':');
234  if (ports) {
235  *ports = '\0';
236  ports++;
237  if ((sscanf(ports, "%5d", &port) != 1) || (port < 1) || (port > 65535)) {
238  fprintf(stderr, "'%s' is not a valid port number in the hostname\n", ports);
239  return -1;
240  }
241  }
242  hp = gethostbyname(host);
243  if (!hp) {
244  fprintf(stderr, "Can't find host '%s'\n", host);
245  return -1;
246  }
247  sock = socket(AF_INET, SOCK_STREAM, 0);
248  if (sock < 0) {
249  fprintf(stderr, "Failed to create socket: %s\n", strerror(errno));
250  return -1;
251  }
252  sin.sin_family = AF_INET;
253  sin.sin_port = htons(port);
254  memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
255  if (connect(sock, (struct sockaddr *)&sin, sizeof(sin))) {
256  fprintf(stderr, "Failed to connect to '%s' port '%d': %s\n", host, port, strerror(errno));
257  close(sock);
258  return -1;
259  }
260  astf = fdopen(sock, "r+");
261  if (!astf) {
262  fprintf(stderr, "fdopen failed: %s\n", strerror(errno));
263  close(sock);
264  return -1;
265  }
266  return 0;
267 }
#define gethostbyname
Definition: lock.h:637
static FILE * astf
Definition: muted.c:209
static char host[256]
Definition: muted.c:77
int errno
static struct hostent * hp
Definition: chan_skinny.c:1236

◆ delete_sub()

static void delete_sub ( struct channel chan,
char *  name 
)
static

Definition at line 565 of file muted.c.

References free(), subchannel::name, subchannel::next, NULL, sub, and channel::subs.

Referenced by hangup_chan().

566 {
567  struct subchannel *sub, *prev;
568  prev = NULL;
569  sub = chan->subs;
570  while(sub) {
571  if (!strcasecmp(sub->name, name)) {
572  if (prev)
573  prev->next = sub->next;
574  else
575  chan->subs = sub->next;
576  free(sub->name);
577  free(sub);
578  return;
579  }
580  prev = sub;
581  sub = sub->next;
582  }
583 }
#define NULL
Definition: resample.c:96
void free()
static const char name[]
Definition: cdr_mysql.c:74
struct subchannel * subs
Definition: muted.c:99
struct stasis_forward * sub
Definition: res_corosync.c:240
char * name
Definition: muted.c:91
struct subchannel * next
Definition: muted.c:92

◆ find_channel()

static struct channel* find_channel ( char *  channel)
static

Definition at line 326 of file muted.c.

References channels, debug, channel::location, channel::next, NULL, channel::tech, and tmp().

Referenced by hangup_chan(), and offhook_chan().

327 {
328  char tmp[256] = "";
329  char *s, *t;
330  struct channel *chan;
331  strncpy(tmp, channel, sizeof(tmp) - 1);
332  s = strchr(tmp, '/');
333  if (s) {
334  *s = '\0';
335  s++;
336  t = strrchr(s, '-');
337  if (t) {
338  *t = '\0';
339  }
340  if (debug)
341  printf("Searching for '%s' tech, '%s' location\n", tmp, s);
342  chan = channels;
343  while(chan) {
344  if (!strcasecmp(chan->tech, tmp) && !strcasecmp(chan->location, s)) {
345  if (debug)
346  printf("Found '%s'/'%s'\n", chan->tech, chan->location);
347  break;
348  }
349  chan = chan->next;
350  }
351  } else
352  chan = NULL;
353  return chan;
354 }
static int tmp()
Definition: bt_open.c:389
char * tech
Definition: muted.c:96
Definition: muted.c:95
#define NULL
Definition: resample.c:96
static struct channel * channels
struct channel * next
Definition: muted.c:98
char * location
Definition: muted.c:97
static int debug
Definition: muted.c:84

◆ get_line()

static char* get_line ( void  )
static

Definition at line 269 of file muted.c.

References astf, buf, and NULL.

Referenced by login_asterisk(), and wait_event().

270 {
271  static char buf[1024];
272  if (fgets(buf, sizeof(buf), astf)) {
273  while(strlen(buf) && (buf[strlen(buf) - 1] < 33))
274  buf[strlen(buf) - 1] = '\0';
275  return buf;
276  } else
277  return NULL;
278 }
static FILE * astf
Definition: muted.c:209
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define NULL
Definition: resample.c:96

◆ getvol()

static int getvol ( void  )
static

Definition at line 357 of file muted.c.

References channels, errno, mixchan, mixfd, and NULL.

Referenced by mute(), and unmute().

358 {
359  int vol;
360 
361  if (ioctl(mixfd, MIXER_READ(mixchan), &vol)) {
362 #else
363 static float getvol(void)
364 {
365  float volumeL, volumeR, vol;
366  OSStatus err;
367  AudioDeviceID device;
368  UInt32 size;
369  UInt32 channels[2];
370  AudioObjectPropertyAddress OutputAddr = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
371  AudioObjectPropertyAddress ChannelAddr = { kAudioDevicePropertyPreferredChannelsForStereo, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementWildcard };
372  AudioObjectPropertyAddress VolumeAddr = { kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeOutput, };
373 
374  size = sizeof(device);
375  err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &OutputAddr, 0, NULL, &size, &device);
376  size = sizeof(channels);
377  if (!err) {
378  err = AudioObjectGetPropertyData(device, &ChannelAddr, 0, NULL, &size, &channels);
379  }
380  size = sizeof(vol);
381  if (!err) {
382  VolumeAddr.mElement = channels[0];
383  err = AudioObjectGetPropertyData(device, &VolumeAddr, 0, NULL, &size, &volumeL);
384  }
385  if (!err) {
386  VolumeAddr.mElement = channels[1];
387  err = AudioObjectGetPropertyData(device, &VolumeAddr, 0, NULL, &size, &volumeR);
388  }
389  if (!err)
390  vol = (volumeL < volumeR) ? volumeR : volumeL;
391  else {
392 #endif
393  fprintf(stderr, "Unable to read mixer volume: %s\n", strerror(errno));
394  return -1;
395  }
396  return vol;
397 }
#define NULL
Definition: resample.c:96
static int mixchan
Definition: muted.c:87
static struct channel * channels
int errno
static int getvol(void)
Definition: muted.c:357
static int mixfd
Definition: muted.c:211

◆ hangup_chan()

static void hangup_chan ( char *  channel)
static

Definition at line 606 of file muted.c.

References check_mute(), debug, delete_sub(), and find_channel().

Referenced by wait_event().

607 {
608  struct channel *chan;
609  if (debug)
610  printf("Hangup '%s'\n", channel);
611  chan = find_channel(channel);
612  if (chan)
613  delete_sub(chan, channel);
614  check_mute();
615 }
static void check_mute(void)
Definition: muted.c:547
static void delete_sub(struct channel *chan, char *name)
Definition: muted.c:565
Definition: muted.c:95
static struct channel * find_channel(char *channel)
Definition: muted.c:326
static int debug
Definition: muted.c:84

◆ load_config()

static int load_config ( void  )
static

Definition at line 123 of file muted.c.

References add_channel(), buf, channels, config, errno, host, mutelevel, pass, and smoothfade.

Referenced by main().

124 {
125  FILE *f;
126  char buf[256];
127  char *val;
128  char *val2;
129  int lineno=0;
130  int x;
131  f = fopen(config, "r");
132  if (!f) {
133  fprintf(stderr, "Unable to open config file '%s': %s\n", config, strerror(errno));
134  return -1;
135  }
136  while(!feof(f)) {
137  if (!fgets(buf, sizeof(buf), f)) {
138  continue;
139  }
140  if (!feof(f)) {
141  lineno++;
142  val = strchr(buf, '#');
143  if (val) *val = '\0';
144  while(strlen(buf) && (buf[strlen(buf) - 1] < 33))
145  buf[strlen(buf) - 1] = '\0';
146  if (!strlen(buf))
147  continue;
148  val = buf;
149  while(*val) {
150  if (*val < 33)
151  break;
152  val++;
153  }
154  if (*val) {
155  *val = '\0';
156  val++;
157  while(*val && (*val < 33)) val++;
158  }
159  if (!strcasecmp(buf, "host")) {
160  if (val && strlen(val))
161  strncpy(host, val, sizeof(host) - 1);
162  else
163  fprintf(stderr, "host needs an argument (the host) at line %d\n", lineno);
164  } else if (!strcasecmp(buf, "user")) {
165  if (val && strlen(val))
166  snprintf(user, sizeof(user), "%s", val);
167  else
168  fprintf(stderr, "user needs an argument (the user) at line %d\n", lineno);
169  } else if (!strcasecmp(buf, "pass")) {
170  if (val && strlen(val))
171  snprintf(pass, sizeof(pass), "%s", val);
172  else
173  fprintf(stderr, "pass needs an argument (the password) at line %d\n", lineno);
174  } else if (!strcasecmp(buf, "smoothfade")) {
175  smoothfade = 1;
176  } else if (!strcasecmp(buf, "mutelevel")) {
177  if (val && (sscanf(val, "%3d", &x) == 1) && (x > -1) && (x < 101)) {
178  mutelevel = x;
179  } else
180  fprintf(stderr, "mutelevel must be a number from 0 (most muted) to 100 (no mute) at line %d\n", lineno);
181  } else if (!strcasecmp(buf, "channel")) {
182  if (val && strlen(val)) {
183  val2 = strchr(val, '/');
184  if (val2) {
185  *val2 = '\0';
186  val2++;
187  add_channel(val, val2);
188  } else
189  fprintf(stderr, "channel needs to be of the format Tech/Location at line %d\n", lineno);
190  } else
191  fprintf(stderr, "channel needs an argument (the channel) at line %d\n", lineno);
192  } else {
193  fprintf(stderr, "ignoring unknown keyword '%s'\n", buf);
194  }
195  }
196  }
197  fclose(f);
198  if (!strlen(host))
199  fprintf(stderr, "no 'host' specification in config file\n");
200  else if (!strlen(user))
201  fprintf(stderr, "no 'user' specification in config file\n");
202  else if (!channels)
203  fprintf(stderr, "no 'channel' specifications in config file\n");
204  else
205  return 0;
206  return -1;
207 }
Definition: ast_expr2.c:325
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static int smoothfade
Definition: muted.c:80
static int mutelevel
Definition: muted.c:81
static char host[256]
Definition: muted.c:77
static struct channel * channels
static char * config
Definition: muted.c:75
int errno
structure to hold users read from users.conf
static void add_channel(char *tech, char *location)
Definition: muted.c:102
static char pass[256]
Definition: muted.c:79

◆ login_asterisk()

static int login_asterisk ( void  )
static

Login to the asterisk manager interface

Definition at line 281 of file muted.c.

References astf, get_line(), and pass.

Referenced by main().

282 {
283  char *welcome;
284  char *resp;
285  if (!(welcome = get_line())) {
286  fprintf(stderr, "disconnected (1)\n");
287  return -1;
288  }
289  fprintf(astf,
290  "Action: Login\r\n"
291  "Username: %s\r\n"
292  "Secret: %s\r\n\r\n", user, pass);
293  if (!(welcome = get_line())) {
294  fprintf(stderr, "disconnected (2)\n");
295  return -1;
296  }
297  if (strcasecmp(welcome, "Response: Success")) {
298  fprintf(stderr, "login failed ('%s')\n", welcome);
299  return -1;
300  }
301  /* Eat the rest of the event */
302  while((resp = get_line()) && strlen(resp));
303  if (!resp) {
304  fprintf(stderr, "disconnected (3)\n");
305  return -1;
306  }
307  fprintf(astf,
308  "Action: Status\r\n\r\n");
309  if (!(welcome = get_line())) {
310  fprintf(stderr, "disconnected (4)\n");
311  return -1;
312  }
313  if (strcasecmp(welcome, "Response: Success")) {
314  fprintf(stderr, "status failed ('%s')\n", welcome);
315  return -1;
316  }
317  /* Eat the rest of the event */
318  while((resp = get_line()) && strlen(resp));
319  if (!resp) {
320  fprintf(stderr, "disconnected (5)\n");
321  return -1;
322  }
323  return 0;
324 }
static FILE * astf
Definition: muted.c:209
static char * get_line(void)
Definition: muted.c:269
structure to hold users read from users.conf
static char pass[256]
Definition: muted.c:79

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 687 of file muted.c.

References astf, connect_asterisk(), debug, errno, load_config(), login_asterisk(), mixfd, needfork, NULL, open_mixer(), usage(), and wait_event().

688 {
689  int x;
690  while((x = getopt(argc, argv, "fhd")) > 0) {
691  switch(x) {
692  case 'd':
693  debug = 1;
694  needfork = 0;
695  break;
696  case 'f':
697  needfork = 0;
698  break;
699  case 'h':
700  /* Fall through */
701  default:
702  usage();
703  exit(1);
704  }
705  }
706  if (load_config())
707  exit(1);
708 #ifndef __Darwin__
709  if (open_mixer())
710  exit(1);
711 #endif
712  if (connect_asterisk()) {
713 #ifndef __Darwin__
714  close(mixfd);
715 #endif
716  exit(1);
717  }
718  if (login_asterisk()) {
719 #ifndef __Darwin__
720  close(mixfd);
721 #endif
722  fclose(astf);
723  exit(1);
724  }
725 #ifdef HAVE_WORKING_FORK
726  if (needfork) {
727 #ifndef HAVE_SBIN_LAUNCHD
728  if (daemon(0,0) < 0) {
729  fprintf(stderr, "daemon() failed: %s\n", strerror(errno));
730  exit(1);
731  }
732 #else
733  const char *found = NULL, *paths[] = {
734  "/Library/LaunchAgents/org.asterisk.muted.plist",
735  "/Library/LaunchDaemons/org.asterisk.muted.plist",
736  "contrib/init.d/org.asterisk.muted.plist",
737  "<path-to-asterisk-source>/contrib/init.d/org.asterisk.muted.plist" };
738  char userpath[256];
739  struct stat unused;
740  struct passwd *pwd = getpwuid(getuid());
741  int i;
742 
743  snprintf(userpath, sizeof(userpath), "%s%s", pwd->pw_dir, paths[0]);
744  if (!stat(userpath, &unused)) {
745  found = userpath;
746  }
747 
748  if (!found) {
749  for (i = 0; i < 3; i++) {
750  if (!stat(paths[i], &unused)) {
751  found = paths[i];
752  break;
753  }
754  }
755  }
756 
757  fprintf(stderr, "Mac OS X detected. Use 'launchctl load -w %s' to launch.\n", found ? found : paths[3]);
758  exit(1);
759 #endif /* !defined(HAVE_SBIN_LAUNCHD */
760  }
761 #endif
762  for(;;) {
763  if (wait_event()) {
764  fclose(astf);
765  while(connect_asterisk()) {
766  sleep(5);
767  }
768  if (login_asterisk()) {
769  fclose(astf);
770  exit(1);
771  }
772  }
773  }
774  exit(0);
775 }
static FILE * astf
Definition: muted.c:209
static int wait_event(void)
Definition: muted.c:628
#define NULL
Definition: resample.c:96
static int connect_asterisk(void)
Definition: muted.c:225
static int login_asterisk(void)
Definition: muted.c:281
static int open_mixer(void)
Definition: muted.c:213
static int load_config(void)
Definition: muted.c:123
int errno
static int mixfd
Definition: muted.c:211
static void usage(void)
Definition: muted.c:680
static int needfork
Definition: muted.c:83
static int debug
Definition: muted.c:84

◆ mute()

static void mute ( void  )
static

Definition at line 468 of file muted.c.

References debug, getvol(), muted, mutedlevel(), mutelevel, setvol(), smoothfade, and stepsize.

Referenced by check_mute().

469 {
470 #ifndef __Darwin__
471  int vol;
472  int start;
473  int x;
474 #else
475  float vol;
476  float start = 1.0;
477  float x;
478 #endif
479  vol = getvol();
480  oldvol = vol;
481  if (smoothfade)
482 #ifdef __Darwin__
483  start = mutelevel;
484 #else
485  start = 100;
486  else
487  start = mutelevel;
488 #endif
489  for (x=start;x>=mutelevel;x-=stepsize) {
490  mutevol = mutedlevel(vol, x);
491  setvol(mutevol);
492  /* Wait 0.01 sec */
493  usleep(10000);
494  }
495  mutevol = mutedlevel(vol, mutelevel);
496  setvol(mutevol);
497  if (debug)
498 #ifdef __Darwin__
499  printf("Mute from '%f' to '%f'!\n", oldvol, mutevol);
500 #else
501  printf("Mute from '%04x' to '%04x'!\n", oldvol, mutevol);
502 #endif
503  muted = 1;
504 }
static int mutevol
Definition: muted.c:443
static int muted
Definition: muted.c:82
static int mutedlevel(int orig, int level)
Definition: muted.c:450
static int smoothfade
Definition: muted.c:80
static int mutelevel
Definition: muted.c:81
static int stepsize
Definition: muted.c:85
static int getvol(void)
Definition: muted.c:357
static int setvol(int vol)
Definition: muted.c:400
static int oldvol
Definition: muted.c:442
static int debug
Definition: muted.c:84

◆ mutedlevel()

static int mutedlevel ( int  orig,
int  level 
)
static

Definition at line 450 of file muted.c.

Referenced by mute(), and unmute().

451 {
452  int l = orig >> 8;
453  int r = orig & 0xff;
454  l = (float)(level) * (float)(l) / 100.0;
455  r = (float)(level) * (float)(r) / 100.0;
456 
457  return (l << 8) | r;
458 #else
459 static float mutedlevel(float orig, float level)
460 {
461  float master = orig;
462  master = level * master / 100.0;
463  return master;
464 #endif
465 
466 }
static int mutedlevel(int orig, int level)
Definition: muted.c:450

◆ offhook_chan()

static void offhook_chan ( char *  channel)
static

Definition at line 617 of file muted.c.

References append_sub(), check_mute(), debug, and find_channel().

Referenced by wait_event().

618 {
619  struct channel *chan;
620  if (debug)
621  printf("Offhook '%s'\n", channel);
622  chan = find_channel(channel);
623  if (chan)
624  append_sub(chan, channel);
625  check_mute();
626 }
static void check_mute(void)
Definition: muted.c:547
Definition: muted.c:95
static void append_sub(struct channel *chan, char *name)
Definition: muted.c:585
static struct channel * find_channel(char *channel)
Definition: muted.c:326
static int debug
Definition: muted.c:84

◆ open_mixer()

static int open_mixer ( void  )
static

Definition at line 213 of file muted.c.

References errno, and mixfd.

Referenced by main().

214 {
215  mixfd = open("/dev/mixer", O_RDWR);
216  if (mixfd < 0) {
217  fprintf(stderr, "Unable to open /dev/mixer: %s\n", strerror(errno));
218  return -1;
219  }
220  return 0;
221 }
int errno
static int mixfd
Definition: muted.c:211

◆ setvol()

static int setvol ( int  vol)
static

Definition at line 400 of file muted.c.

References channels, errno, mixchan, mixfd, and NULL.

Referenced by mute(), and unmute().

404 {
405 #ifndef __Darwin__
406  if (ioctl(mixfd, MIXER_WRITE(mixchan), &vol)) {
407 #else
408  float volumeL = vol;
409  float volumeR = vol;
410  OSStatus err;
411  AudioDeviceID device;
412  UInt32 size;
413  UInt32 channels[2];
414  AudioObjectPropertyAddress OutputAddr = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
415  AudioObjectPropertyAddress ChannelAddr = { kAudioDevicePropertyPreferredChannelsForStereo, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementWildcard };
416  AudioObjectPropertyAddress VolumeAddr = { kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeOutput, };
417 
418  size = sizeof(device);
419  err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &OutputAddr, 0, NULL, &size, &device);
420  size = sizeof(channels);
421  err = AudioObjectGetPropertyData(device, &ChannelAddr, 0, NULL, &size, &channels);
422  size = sizeof(vol);
423  if (!err) {
424  VolumeAddr.mElement = channels[0];
425  err = AudioObjectSetPropertyData(device, &VolumeAddr, 0, NULL, size, &volumeL);
426  }
427  if (!err) {
428  VolumeAddr.mElement = channels[1];
429  err = AudioObjectSetPropertyData(device, &VolumeAddr, 0, NULL, size, &volumeR);
430  }
431  if (err) {
432 #endif
433 
434  fprintf(stderr, "Unable to write mixer volume: %s\n", strerror(errno));
435  return -1;
436 
437  }
438  return 0;
439 }
#define NULL
Definition: resample.c:96
static int mixchan
Definition: muted.c:87
static struct channel * channels
int errno
static int mixfd
Definition: muted.c:211

◆ unmute()

static void unmute ( void  )
static

Definition at line 506 of file muted.c.

References debug, getvol(), muted, mutedlevel(), mutelevel, setvol(), smoothfade, and stepsize.

Referenced by check_mute().

507 {
508 #ifdef __Darwin__
509  float vol;
510  float start;
511  float x;
512 #else
513  int vol;
514  int start;
515  int x;
516 #endif
517  vol = getvol();
518  if (debug)
519 #ifdef __Darwin__
520  printf("Unmute from '%f' (should be '%f') to '%f'!\n", vol, mutevol, oldvol);
521  mutevol = vol;
522  if (vol == mutevol) {
523 #else
524  printf("Unmute from '%04x' (should be '%04x') to '%04x'!\n", vol, mutevol, oldvol);
525  if ((int)vol == mutevol) {
526 #endif
527  if (smoothfade)
528  start = mutelevel;
529  else
530 #ifdef __Darwin__
531  start = 1.0;
532 #else
533  start = 100;
534 #endif
535  for (x=start;x<100;x+=stepsize) {
536  mutevol = mutedlevel(oldvol, x);
537  setvol(mutevol);
538  /* Wait 0.01 sec */
539  usleep(10000);
540  }
541  setvol(oldvol);
542  } else
543  printf("Whoops, it's already been changed!\n");
544  muted = 0;
545 }
static int mutevol
Definition: muted.c:443
static int muted
Definition: muted.c:82
static int mutedlevel(int orig, int level)
Definition: muted.c:450
static int smoothfade
Definition: muted.c:80
static int mutelevel
Definition: muted.c:81
static int stepsize
Definition: muted.c:85
static int getvol(void)
Definition: muted.c:357
static int setvol(int vol)
Definition: muted.c:400
static int oldvol
Definition: muted.c:442
static int debug
Definition: muted.c:84

◆ usage()

static void usage ( void  )
static

Definition at line 680 of file muted.c.

Referenced by main().

681 {
682  printf("Usage: muted [-f] [-d]\n"
683  " -f : Do not fork\n"
684  " -d : Debug (implies -f)\n");
685 }

◆ wait_event()

static int wait_event ( void  )
static

Definition at line 628 of file muted.c.

References get_line(), hangup_chan(), and offhook_chan().

Referenced by main().

629 {
630  char *resp;
631  char event[120]="";
632  char channel[120]="";
633  char oldname[120]="";
634  char newname[120]="";
635 
636  resp = get_line();
637  if (!resp) {
638  fprintf(stderr, "disconnected (6)\n");
639  return -1;
640  }
641  if (!strncasecmp(resp, "Event: ", strlen("Event: "))) {
642  int event_len = -1;
643  int channel_len = -1;
644  int newname_len = -1;
645  int oldname_len = -1;
646 
647  event_len = snprintf(event, sizeof(event), "%s", resp + strlen("Event: "));
648  /* Consume the rest of the non-event */
649  while((resp = get_line()) && strlen(resp)) {
650  if (!strncasecmp(resp, "Channel: ", strlen("Channel: ")))
651  channel_len = snprintf(channel, sizeof(channel), "%s", resp + strlen("Channel: "));
652  if (!strncasecmp(resp, "Newname: ", strlen("Newname: ")))
653  newname_len = snprintf(newname, sizeof(newname), "%s", resp + strlen("Newname: "));
654  if (!strncasecmp(resp, "Oldname: ", strlen("Oldname: ")))
655  oldname_len = snprintf(oldname, sizeof(oldname), "%s", resp + strlen("Oldname: "));
656  }
657  if (channel_len == strlen(channel)) {
658  if (event_len == strlen(event) && !strcasecmp(event, "Hangup"))
659  hangup_chan(channel);
660  else
661  offhook_chan(channel);
662  }
663  if (newname_len == strlen(newname) && oldname_len == strlen(oldname)) {
664  if (event_len == strlen(event) && !strcasecmp(event, "Rename")) {
665  hangup_chan(oldname);
666  offhook_chan(newname);
667  }
668  }
669  } else {
670  /* Consume the rest of the non-event */
671  while((resp = get_line()) && strlen(resp));
672  }
673  if (!resp) {
674  fprintf(stderr, "disconnected (7)\n");
675  return -1;
676  }
677  return 0;
678 }
static void offhook_chan(char *channel)
Definition: muted.c:617
Definition: astman.c:222
Definition: muted.c:95
static void hangup_chan(char *channel)
Definition: muted.c:606
static char * get_line(void)
Definition: muted.c:269

Variable Documentation

◆ astf

FILE* astf
static

Definition at line 209 of file muted.c.

Referenced by connect_asterisk(), get_line(), login_asterisk(), and main().

◆ channels

struct channel * channels
static

◆ config

char* config = "/etc/asterisk/muted.conf"
static

Definition at line 75 of file muted.c.

Referenced by load_config().

◆ debug

int debug = 0
static

Definition at line 84 of file muted.c.

Referenced by find_channel(), hangup_chan(), main(), mute(), offhook_chan(), and unmute().

◆ host

char host[256] = ""
static

◆ mixchan

int mixchan = SOUND_MIXER_VOLUME
static

Definition at line 87 of file muted.c.

Referenced by getvol(), and setvol().

◆ mixfd

int mixfd
static

Definition at line 211 of file muted.c.

Referenced by getvol(), main(), open_mixer(), and setvol().

◆ muted

int muted = 0
static

◆ mutelevel

int mutelevel = 20
static

Definition at line 81 of file muted.c.

Referenced by load_config(), mute(), and unmute().

◆ mutevol

int mutevol = 0
static

Definition at line 443 of file muted.c.

◆ needfork

int needfork = 1
static

Definition at line 83 of file muted.c.

Referenced by main().

◆ oldvol

int oldvol = 0
static

Definition at line 442 of file muted.c.

◆ pass

char pass[256] = ""
static

Definition at line 79 of file muted.c.

Referenced by load_config(), and login_asterisk().

◆ smoothfade

int smoothfade = 0
static

Definition at line 80 of file muted.c.

Referenced by load_config(), mute(), and unmute().

◆ stepsize

int stepsize = 3
static

Definition at line 85 of file muted.c.

Referenced by mute(), and unmute().

◆ user

char user[256] = ""
static

Definition at line 78 of file muted.c.