Index: channels/chan_sip.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v retrieving revision 1.827 diff -u -r1.827 chan_sip.c --- channels/chan_sip.c 30 Aug 2005 02:12:09 -0000 1.827 +++ channels/chan_sip.c 30 Aug 2005 20:06:18 -0000 @@ -415,10 +415,8 @@ #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 +#define DEC_CALL_LIMIT 0 +#define INC_CALL_LIMIT 1 static struct ast_codec_pref prefs; @@ -674,9 +672,8 @@ int callingpres; /* Calling id presentation */ int capability; /* Codec capability */ int inUse; /* Number of calls in use */ - int incominglimit; /* Limit of incoming calls */ + int call_limit; /* Limit of concurrent calls */ int outUse; /* disabled */ - int outgoinglimit; /* disabled */ struct ast_ha *ha; /* ACL setting */ struct ast_variable *chanvars; /* Variables to set for channel created by user */ }; @@ -702,9 +699,8 @@ char cid_name[80]; /* Caller ID name */ int callingpres; /* Calling id presentation */ int inUse; /* Number of calls in use */ - int incominglimit; /* Limit of incoming calls */ + int call_limit; /* Limit of concurrent calls */ int outUse; /* disabled */ - int outgoinglimit; /* disabled */ char vmexten[AST_MAX_EXTENSION]; /* Dialplan extension for MWI notify message*/ char mailbox[AST_MAX_EXTENSION]; /* Mailbox setting for MWI checks */ char language[MAX_LANGUAGE]; /* Default language for prompts */ @@ -840,7 +836,7 @@ static int do_proxy_auth(struct sip_pvt *p, struct sip_request *req, char *header, char *respheader, int sipmethod, int init); static void free_old_route(struct sip_route *route); static int build_reply_digest(struct sip_pvt *p, int method, char *digest, int digest_len); -static int update_user_counter(struct sip_pvt *fup, int event); +static int update_call_counter(struct sip_pvt *fup, int event); static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int realtime); static struct sip_user *build_user(const char *name, struct ast_variable *v, int realtime); static int sip_do_reload(void); @@ -1819,6 +1815,8 @@ r->rtptimeout = peer->rtptimeout; r->rtpholdtimeout = peer->rtpholdtimeout; r->rtpkeepalive = peer->rtpkeepalive; + if (peer->call_limit) + ast_set_flag(r, SIP_CALL_LIMIT); return 0; } @@ -1939,7 +1937,7 @@ } else if (!options.distinctive_ring && !strcasecmp(ast_var_name(current),"ALERT_INFO")) { /* Check whether there is a ALERT_INFO variable */ options.distinctive_ring = ast_var_value(current); - } else if (!options.addsipheaders && !strncasecmp(ast_var_name(current),"SIPADDHEADER",strlen("SIPADDHEADER"))) { + } else if (!options.addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { /* Check whether there is a variable with a name starting with SIPADDHEADER */ options.addsipheaders = 1; } @@ -1966,7 +1964,7 @@ } #endif ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); - res = update_user_counter(p,INC_OUT_USE); + res = update_call_counter(p, INC_CALL_LIMIT); if ( res != -1 ) { p->callingpres = ast->cid.cid_pres; p->jointcapability = p->capability; @@ -2084,16 +2082,19 @@ free(p); } -/*--- update_user_counter: Handle incominglimit and outgoinglimit for SIP users ---*/ +/*--- update_call_counter: Handle call_limit for SIP users ---*/ /* Note: This is going to be replaced by app_groupcount */ /* Thought: For realtime, we should propably update storage with inuse counter... */ -static int update_user_counter(struct sip_pvt *fup, int event) +static int update_call_counter(struct sip_pvt *fup, int event) { char name[256] = ""; - struct sip_user *u; - struct sip_peer *p; - int *inuse, *incominglimit; + int *inuse, *call_limit; + int outgoing = ast_test_flag(fup, SIP_OUTGOING); + struct sip_user *u = NULL; + struct sip_peer *p = NULL; + if (option_debug > 2) + ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); /* Test if we need to check call limits, in order to avoid realtime lookups if we do not need it */ if (!ast_test_flag(fup, SIP_CALL_LIMIT)) @@ -2105,14 +2106,15 @@ u = find_user(name, 1); if (u) { inuse = &u->inUse; - incominglimit = &u->incominglimit; + call_limit = &u->call_limit; p = NULL; } else { /* Try to find peer */ - p = find_peer(fup->peername, NULL, 1); + if (!p) + p = find_peer(fup->peername, NULL, 1); if (p) { inuse = &p->inUse; - incominglimit = &p->incominglimit; + call_limit = &p->call_limit; ast_copy_string(name, fup->peername, sizeof(name)); } else { if (option_debug > 1) @@ -2122,21 +2124,20 @@ } switch(event) { /* incoming and outgoing affects the inUse counter */ - case DEC_OUT_USE: - case DEC_IN_USE: + case DEC_CALL_LIMIT: if ( *inuse > 0 ) { (*inuse)--; } else { *inuse = 0; } + ast_log(LOG_ERROR, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); break; - case INC_IN_USE: - case INC_OUT_USE: - if (*incominglimit > 0 ) { - if (*inuse >= *incominglimit) { - ast_log(LOG_ERROR, "Call from %s '%s' rejected due to usage limit of %d\n", u?"user":"peer", name, *incominglimit); + case INC_CALL_LIMIT: + if (*call_limit > 0 ) { + if (*inuse >= *call_limit) { + ast_log(LOG_ERROR, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); /* inc inUse as well */ - if ( event == INC_OUT_USE ) { + if ( event == INC_CALL_LIMIT ) { (*inuse)++; } if (u) @@ -2147,33 +2148,10 @@ } } (*inuse)++; - ast_log(LOG_DEBUG, "Call from %s '%s' is %d out of %d\n", u?"user":"peer", name, *inuse, *incominglimit); - break; -#ifdef DISABLED_CODE - /* we don't use these anymore */ - 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); - if (u->temponly) { - destroy_user(u); - } - return -1; - } - } - u->outUse++; + ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); break; -#endif default: - ast_log(LOG_ERROR, "update_user_counter(%s,%d) called with no event!\n",name,event); + ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); } if (u) ASTOBJ_UNREF(u,sip_destroy_user); @@ -2328,13 +2306,8 @@ ast_osp_terminate(p->osphandle, AST_CAUSE_NORMAL, p->ospstart, time(NULL) - p->ospstart); } #endif - if (ast_test_flag(p, SIP_OUTGOING)) { - ast_log(LOG_DEBUG, "update_user_counter(%s) - decrement outUse counter\n", p->username); - update_user_counter(p, DEC_OUT_USE); - } else { - ast_log(LOG_DEBUG, "update_user_counter(%s) - decrement inUse counter\n", p->username); - update_user_counter(p, DEC_IN_USE); - } + ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter\n", p->username); + update_call_counter(p, DEC_CALL_LIMIT); /* Determine how to disconnect */ if (p->owner != ast) { ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); @@ -2372,12 +2345,7 @@ if ( p->initid != -1 ) { /* channel still up - reverse dec of inUse counter only if the channel is not auto-congested */ - if (ast_test_flag(p, SIP_OUTGOING)) { - update_user_counter(p, INC_OUT_USE); - } - else { - update_user_counter(p, INC_IN_USE); - } + update_call_counter(p, INC_CALL_LIMIT); } } else { /* Incoming call, not up */ char *res; @@ -2729,7 +2697,7 @@ } ast_setstate(tmp, state); if (state != AST_STATE_DOWN) { - if (ast_pbx_start(tmp)) { + if (ast_pbx_start(tmp)) { ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); ast_hangup(tmp); tmp = NULL; @@ -6569,7 +6537,7 @@ user->sipoptions = p->sipoptions; /* If we have a call limit, set flag */ - if (user->incominglimit) + if (user->call_limit) ast_set_flag(p, SIP_CALL_LIMIT); if (!ast_strlen_zero(user->context)) ast_copy_string(p->context, user->context, sizeof(p->context)); @@ -6658,7 +6626,7 @@ if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, p->peersecret, p->peermd5secret, sipmethod, uri, reliable, ignore))) { ast_copy_flags(p, peer, SIP_PROMISCREDIR | SIP_DTMF | SIP_REINVITE); /* If we have a call limit, set flag */ - if (peer->incominglimit) + if (peer->call_limit) ast_set_flag(p, SIP_CALL_LIMIT); ast_copy_string(p->peername, peer->name, sizeof(p->peername)); ast_copy_string(p->authname, peer->name, sizeof(p->authname)); @@ -6795,7 +6763,7 @@ } /*--- sip_show_inuse: CLI Command to show calls within limits set by - incominglimit ---*/ + call_limit ---*/ static int sip_show_inuse(int fd, int argc, char *argv[]) { #define FORMAT "%-25.25s %-15.15s %-15.15s \n" #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" @@ -6812,19 +6780,12 @@ ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { ASTOBJ_RDLOCK(iterator); - if (iterator->incominglimit) - snprintf(ilimits, sizeof(ilimits), "%d", iterator->incominglimit); + if (iterator->call_limit) + snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); else ast_copy_string(ilimits, "N/A", sizeof(ilimits)); - /* Code disabled ---------------------------- - if (iterator->outgoinglimit) - snprintf(olimits, sizeof(olimits), "%d", iterator->outgoinglimit); - else - ast_copy_string(olimits, "N/A", sizeof(olimits)); - snprintf(oused, sizeof(oused), "%d", iterator->outUse); - ---------------------------------------------*/ snprintf(iused, sizeof(iused), "%d", iterator->inUse); - if (showall || iterator->incominglimit) + if (showall || iterator->call_limit) ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); ASTOBJ_UNLOCK(iterator); } while (0) ); @@ -6833,19 +6794,12 @@ ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { ASTOBJ_RDLOCK(iterator); - if (iterator->incominglimit) - snprintf(ilimits, sizeof(ilimits), "%d", iterator->incominglimit); + if (iterator->call_limit) + snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); else ast_copy_string(ilimits, "N/A", sizeof(ilimits)); - /* Code disabled ---------------------------- - if (iterator->outgoinglimit) - snprintf(olimits, sizeof(olimits), "%d", iterator->outgoinglimit); - else - ast_copy_string(olimits, "N/A", sizeof(olimits)); - snprintf(oused, sizeof(oused), "%d", iterator->outUse); - ---------------------------------------------*/ snprintf(iused, sizeof(iused), "%d", iterator->inUse); - if (showall || iterator->incominglimit) + if (showall || iterator->call_limit) ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); ASTOBJ_UNLOCK(iterator); } while (0) ); @@ -7434,8 +7388,7 @@ ast_cli(fd, " Mailbox : %s\n", peer->mailbox); ast_cli(fd, " VM Extension : %s\n", peer->vmexten); ast_cli(fd, " LastMsgsSent : %d\n", peer->lastmsgssent); - ast_cli(fd, " Inc. limit : %d\n", peer->incominglimit); - ast_cli(fd, " Outg. limit : %d\n", peer->outgoinglimit); + ast_cli(fd, " Call limit : %d\n", peer->call_limit); ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(peer, SIP_DYNAMIC)?"Yes":"No")); ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); ast_cli(fd, " Expire : %d\n", peer->expire); @@ -7510,8 +7463,7 @@ print_group(fd, peer->pickupgroup); ast_cli(fd, "VoiceMailbox: %s\r\n", peer->mailbox); ast_cli(fd, "LastMsgsSent: %d\r\n", peer->lastmsgssent); - ast_cli(fd, "Incominglimit: %d\r\n", peer->incominglimit); - ast_cli(fd, "Outgoinglimit: %d\r\n", peer->outgoinglimit); + ast_cli(fd, "Call limit: %d\r\n", peer->call_limit); ast_cli(fd, "Dynamic: %s\r\n", (ast_test_flag(peer, SIP_DYNAMIC)?"Y":"N")); ast_cli(fd, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); ast_cli(fd, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); @@ -7594,8 +7546,7 @@ ast_cli(fd, " Accountcode : %s\n", user->accountcode); ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); - ast_cli(fd, " Inc. limit : %d\n", user->incominglimit); - ast_cli(fd, " Outg. limit : %d\n", user->outgoinglimit); + ast_cli(fd, " Call limit : %d\n", user->call_limit); ast_cli(fd, " Callgroup : "); print_group(fd, user->callgroup); ast_cli(fd, " Pickupgroup : "); @@ -8714,7 +8665,7 @@ } else if (!strcasecmp(colname, "regexten")) { ast_copy_string(buf, peer->regexten, len); } else if (!strcasecmp(colname, "limit")) { - snprintf(buf, len, "%d", peer->incominglimit); + snprintf(buf, len, "%d", peer->call_limit); } else if (!strcasecmp(colname, "curcalls")) { snprintf(buf, len, "%d", peer->inUse); } else if (!strcasecmp(colname, "useragent")) { @@ -8772,9 +8723,9 @@ "- codecs The configured codecs.\n" "- status Status (if qualify=yes).\n" "- regexten Registration extension\n" - "- limit Call limit (incominglimit)\n" + "- limit Call limit (call-limit)\n" "- curcalls Current amount of calls \n" - " Only available if incominglimit is set\n" + " Only available if call-limit is set\n" "- language Default language for peer\n" "- useragent Current user agent id for peer\n" "- codec[x] Preferred codec index number 'x' (beginning with zero).\n" @@ -9298,12 +9249,7 @@ break; case 487: /* channel now destroyed - dec the inUse counter */ - if (ast_test_flag(p, SIP_OUTGOING)) { - update_user_counter(p, DEC_OUT_USE); - } - else { - update_user_counter(p, DEC_IN_USE); - } + update_call_counter(p, DEC_CALL_LIMIT); break; case 482: /* SIP is incapable of performing a hairpin call, which is yet another failure of not having a layer 2 (again, YAY @@ -9673,7 +9619,7 @@ strcpy(p->context, default_context); /* Check number of concurrent calls -vs- incoming limit HERE */ ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); - res = update_user_counter(p, INC_IN_USE); + res = update_call_counter(p, INC_CALL_LIMIT); if (res) { if (res < 0) { ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); @@ -9697,13 +9643,13 @@ transmit_response(p, "404 Not Found", req); else transmit_response_reliable(p, "404 Not Found", req, 1); - update_user_counter(p,DEC_IN_USE); + update_call_counter(p, DEC_CALL_LIMIT); } else { if (ignore) transmit_response(p, "484 Address Incomplete", req); else transmit_response_reliable(p, "484 Address Incomplete", req, 1); - update_user_counter(p,DEC_IN_USE); + update_call_counter(p, DEC_CALL_LIMIT); } ast_set_flag(p, SIP_NEEDDESTROY); } else { @@ -10724,7 +10670,7 @@ * call control with incominglimit=X in sip.conf where X > 0 * Check if the device has incominglimit, and if qualify=on, if the device * is reachable */ - if (p->incominglimit && (p->lastms == 0 || p->lastms <= p->maxms)) { /* Free for a call */ + if (p->call_limit && (p->lastms == 0 || p->lastms <= p->maxms)) { /* Free for a call */ res = AST_DEVICE_NOT_INUSE; if (p->inUse) /* On a call */ res = AST_DEVICE_BUSY; @@ -11096,14 +11042,10 @@ ast_copy_string(user->musicclass, v->value, sizeof(user->musicclass)); } else if (!strcasecmp(v->name, "accountcode")) { ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); - } else if (!strcasecmp(v->name, "incominglimit")) { - 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, "call-limit") || !strcasecmp(v->name, "incominglimit")) { + user->call_limit = atoi(v->value); + if (user->call_limit < 0) + user->call_limit = 0; } else if (!strcasecmp(v->name, "amaflags")) { format = ast_cdr_amaflags2int(v->value); if (format < 0) { @@ -11347,14 +11289,10 @@ ast_copy_string(peer->language, v->value, sizeof(peer->language)); } else if (!strcasecmp(v->name, "regexten")) { ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); - } else if (!strcasecmp(v->name, "incominglimit")) { - peer->incominglimit = atoi(v->value); - if (peer->incominglimit < 0) - peer->incominglimit = 0; - } else if (!strcasecmp(v->name, "outgoinglimit")) { - peer->outgoinglimit = atoi(v->value); - if (peer->outgoinglimit < 0) - peer->outgoinglimit = 0; + } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { + peer->call_limit = atoi(v->value); + if (peer->call_limit < 0) + peer->call_limit = 0; } else if (!strcasecmp(v->name, "amaflags")) { format = ast_cdr_amaflags2int(v->value); if (format < 0) { Index: configs/sip.conf.sample =================================================================== RCS file: /usr/cvsroot/asterisk/configs/sip.conf.sample,v retrieving revision 1.66 diff -u -r1.66 sip.conf.sample --- configs/sip.conf.sample 25 Aug 2005 02:25:30 -0000 1.66 +++ configs/sip.conf.sample 30 Aug 2005 20:06:19 -0000 @@ -234,7 +234,7 @@ ; setvar setvar ; callerid callerid ; amaflags amaflags -; incominglimit incominglimit +; call-limit call-limit ; restrictcid restrictcid ; mailbox ; username @@ -266,6 +266,7 @@ ;fromdomain=provider.sip.domain ;host=box.provider.com ;usereqphone=yes ; This provider requires ";user=phone" on URI +;call-limit=5 ; permit only 5 simultaneous outgoing calls to this peer ;------------------------------------------------------------------------------ ; Definitions of locally connected SIP phones @@ -290,8 +291,11 @@ ;nat=no ; there is not NAT between phone and Asterisk ;canreinvite=yes ; allow RTP voice traffic to bypass Asterisk ;dtmfmode=info ; either RFC2833 or INFO for the BudgeTone -;incominglimit=1 ; permit only 1 outgoing call at a time +;call-limit=1 ; permit only 1 outgoing call and 1 incoming call at a time ; from the phone to asterisk + ; (1 for the explicit peer, 1 for the explicit user, + ; remember that a friend equals 1 peer and 1 user in + ; memory) ;mailbox=1234@default ; mailbox 1234 in voicemail context "default" ;disallow=all ; need to disallow=all before we can use allow= ;allow=ulaw ; Note: In user sections the order of codecs