Index: chan_sip.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v retrieving revision 1.172 diff -u -r1.172 chan_sip.c --- chan_sip.c 5 Sep 2003 04:00:57 -0000 1.172 +++ chan_sip.c 5 Sep 2003 15:32:13 -0000 @@ -147,6 +147,11 @@ #define SIP_MAX_HEADERS 64 #define SIP_MAX_LINES 64 +#define DEC_IN_USE 0 +#define INC_IN_USE 1 +#define DEC_OUT_USE 2 +#define INC_OUT_USE 3 + static struct sip_codec_pref { int codec; struct sip_codec_pref *next; @@ -279,6 +284,8 @@ int dtmfmode; int inUse; int incominglimit; + int outUse; + int outgoinglimit; int restrictcid; struct ast_ha *ha; struct sip_user *next; @@ -391,6 +398,7 @@ static char *getsipuri(char *header); static void free_old_route(struct sip_route *route); static int build_reply_digest(struct sip_pvt *p, char *orig_header, char *digest, int digest_len); +static int find_user(struct sip_pvt *fup, int event); static int __sip_xmit(struct sip_pvt *p, char *data, int len) { @@ -850,6 +858,8 @@ res = 0; p->outgoing = 1; + ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); + res = find_user(p,INC_OUT_USE); p->restrictcid = ast->restrictcid; transmit_invite(p, "INVITE", 1, NULL, vxml_url,distinctive_ring, 1); if (p->maxtime) { @@ -939,22 +949,44 @@ ast_mutex_unlock(&userl.lock); return 0; } - if(event == 0) { - if ( u->inUse > 0 ) { - u->inUse = u->inUse - 1; - } else { - u->inUse = 0; - } - } else { - if (u->incominglimit > 0 ) { - if (u->inUse >= u->incominglimit) { - ast_log(LOG_ERROR, "Call from user '%s' rejected due to usage limit of %d\n", u->name, u->incominglimit); - ast_mutex_unlock(&userl.lock); - return -1; + switch(event) { + case DEC_IN_USE: + if ( u->inUse > 0 ) { + u->inUse--; + } else { + u->inUse = 0; } - } - u->inUse++; - ast_log(LOG_DEBUG, "Call from user '%s' is %d out of %d\n", u->name, u->inUse, u->incominglimit); + break; + case INC_IN_USE: + if (u->incominglimit > 0 ) { + if (u->inUse >= u->incominglimit) { + ast_log(LOG_ERROR, "Call from user '%s' rejected due to usage limit of %d\n", u->name, u->incominglimit); + ast_mutex_unlock(&userl.lock); + return -1; + } + } + u->inUse++; + ast_log(LOG_DEBUG, "Call from user '%s' is %d out of %d\n", u->name, u->inUse, u->incominglimit); + break; + case DEC_OUT_USE: + if ( u->outUse > 0 ) { + u->outUse--; + } else { + u->outUse = 0; + } + break; + case INC_OUT_USE: + if ( u->outgoinglimit > 0 ) { + if ( u->outUse >= u->outgoinglimit ) { + ast_log(LOG_ERROR, "Outgoing call from user '%s' rejected due to usage limit of %d\n", u->name, u->outgoinglimit); + ast_mutex_unlock(&userl.lock); + return -1; + } + } + u->outUse++; + break; + default: + ast_log(LOG_ERROR, "find_user(%s,%d) called with no event!\n",u->name,event); } ast_mutex_unlock(&userl.lock); return 0; @@ -982,8 +1014,13 @@ return 0; } ast_mutex_lock(&p->lock); - ast_log(LOG_DEBUG, "find_user(%s)\n", p->username); - find_user(p, 0); + if ( p->outgoing ) { + ast_log(LOG_DEBUG, "find_user(%s) - decrement outUse counter\n", p->username); + find_user(p, DEC_OUT_USE); + } else { + ast_log(LOG_DEBUG, "find_user(%s) - decrement inUse counter\n", p->username); + find_user(p, DEC_IN_USE); + } /* Determine how to disconnect */ if (p->owner != ast) { ast_log(LOG_WARNING, "Huh? We aren't the owner?\n"); @@ -3902,23 +3939,30 @@ } static int sip_show_inuse(int fd, int argc, char *argv[]) { -#define FORMAT "%-15.15s %-15.15s %-15.15s\n" -#define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" +#define FORMAT "%-15.15s %-15.15s %-15.15s %-15.15s %-15.15s\n" +#define FORMAT2 "%-15.15s %-15.15s %-15.15s %-15.15s %-15.15s\n" struct sip_user *user; - char limits[80]; - char used[80]; + char ilimits[40]; + char olimits[40]; + char iused[40]; + char oused[40]; if (argc != 3) return RESULT_SHOWUSAGE; ast_mutex_lock(&userl.lock); user = userl.users; - ast_cli(fd, FORMAT, "Username", "inUse", "Limit"); + ast_cli(fd, FORMAT, "Username", "incoming", "Limit","outgoing","Limit"); for(user=userl.users;user;user=user->next) { if (user->incominglimit) - snprintf(limits, sizeof(limits), "%d", user->incominglimit); + snprintf(ilimits, sizeof(ilimits), "%d", user->incominglimit); + else + strcpy(ilimits, "N/A"); + if (user->outgoinglimit) + snprintf(olimits, sizeof(olimits), "%d", user->outgoinglimit); else - strcpy(limits, "N/A"); - snprintf(used, sizeof(used), "%d", user->inUse); - ast_cli(fd, FORMAT2, user->name, used, limits); + strcpy(olimits, "N/A"); + snprintf(iused, sizeof(iused), "%d", user->inUse); + snprintf(oused, sizeof(oused), "%d", user->outUse); + ast_cli(fd, FORMAT2, user->name, iused, ilimits,oused,olimits); } ast_mutex_unlock(&userl.lock); return RESULT_SUCCESS; @@ -4301,7 +4345,7 @@ static char show_inuse_usage[] = "Usage: sip show inuse\n" -" List all users known to the SIP (Session Initiation Protocol) subsystem inUse counters and their incominglimit.\n"; +" List all users known to the SIP (Session Initiation Protocol) subsystem usage counters and limits.\n"; static char show_channels_usage[] = "Usage: sip show channels\n" @@ -4814,8 +4858,8 @@ if (!strlen(p->context)) strncpy(p->context, context, sizeof(p->context) - 1); /* Check number of concurrent calls -vs- incoming limit HERE */ - ast_log(LOG_DEBUG, "Check for res\n"); - res = find_user(p,1); + ast_log(LOG_DEBUG, "Check for res for %s\n", p->username); + res = find_user(p,INC_IN_USE); if (res) { if (res < 0) { ast_log(LOG_DEBUG, "Failed to place call for user %s, too many calls\n", p->username); @@ -4832,10 +4876,10 @@ if (gotdest) { if (gotdest < 0) { transmit_response(p, "404 Not Found", req); - find_user(p,0); + find_user(p,DEC_IN_USE); } else { transmit_response(p, "484 Address Incomplete", req); - find_user(p,0); + find_user(p,DEC_IN_USE); } p->needdestroy = 1; } else { @@ -5497,6 +5541,7 @@ /* set the usage flag to a sane staring value*/ user->inUse = 0; + user->outUse = 0; user->canreinvite = REINVITE_INVITE; /* JK02: set default context */ @@ -5542,6 +5587,10 @@ user->incominglimit = atoi(v->value); if (user->incominglimit < 0) user->incominglimit = 0; + } else if (!strcasecmp(v->name, "outgoinglimit")) { + user->outgoinglimit = atoi(v->value); + if (user->outgoinglimit < 0) + user->outgoinglimit = 0; } else if (!strcasecmp(v->name, "amaflags")) { format = ast_cdr_amaflags2int(v->value); if (format < 0) {