Index: channels/chan_sip.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v retrieving revision 1.669 diff -u -r1.669 chan_sip.c --- channels/chan_sip.c 26 Feb 2005 16:29:15 -0000 1.669 +++ channels/chan_sip.c 1 Mar 2005 13:35:56 -0000 @@ -116,10 +116,46 @@ static char *config = "sip.conf"; static char *notify_config = "sip_notify.conf"; +#define SIP_REGISTER 1 +#define SIP_OPTIONS 2 +#define SIP_NOTIFY 3 +#define SIP_INVITE 4 +#define SIP_ACK 5 +#define SIP_PRACK 6 +#define SIP_BYE 7 +#define SIP_REFER 8 +#define SIP_SUBSCRIBE 9 +#define SIP_MESSAGE 10 +#define SIP_UPDATE 11 +#define SIP_INFO 12 +#define SIP_CANCEL 13 +#define SIP_MAX_METHODS 13 +#define SIP_RESPONSE 100 + +const struct cfsip_methods { + int id; + char *method; +} sip_methods[] = { + { SIP_REGISTER, "REGISTER" }, + { SIP_OPTIONS, "OPTIONS" }, + { SIP_NOTIFY, "NOTIFY" }, + { SIP_INVITE, "INVITE" }, + { SIP_ACK, "ACK" }, + { SIP_PRACK, "PRACK" }, + { SIP_BYE, "BYE" }, + { SIP_REFER, "REFER" }, + { SIP_SUBSCRIBE,"SUBSCRIBE" }, + { SIP_MESSAGE, "MESSAGE" }, + { SIP_UPDATE, "UPDATE" }, + { SIP_INFO, "INFO" }, + { SIP_CANCEL, "CANCEL" } +}; + + #define DEFAULT_SIP_PORT 5060 /* From RFC 2543 */ #define SIP_MAX_PACKET 4096 /* Also from RFC 2543, should sub headers tho */ -#define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER" +#define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE" static char default_useragent[AST_MAX_EXTENSION] = DEFAULT_USERAGENT; @@ -318,6 +354,7 @@ /* sip_pvt: PVT structures are used for each SIP conversation, ie. a call */ static struct sip_pvt { ast_mutex_t lock; /* Channel private lock */ + int method; /* SIP method of this packet */ char callid[80]; /* Global CallID */ char randdata[80]; /* Random data */ struct ast_codec_pref prefs; /* codec prefs */ @@ -6050,14 +6087,63 @@ #undef FORMAT } +static char mandescr_show_peers[] = +"Description: Lists SIP peers in text format with details on current status.\n" +" The XML format is under development, feedback welcome! /oej\n" +"Variables: \n" +" ActionID: Action ID for this transaction. Will be returned.\n" +" Accept: Indication of accepted output.\n" +" Default: text/plain\n" +" text/xml will give XML output.\n"; + +static int _sip_show_peers(int type, int fd, struct mansession *s, struct message *m, int argc, char *argv[]); + +/*--- manager_sip_show_peers: Show SIP peers in the manager API ---*/ +/* Inspired from chan_iax2 */ +static int manager_sip_show_peers( struct mansession *s, struct message *m ) +{ + char *id = astman_get_header(m,"ActionID"); + char *format = astman_get_header(m, "Accept"); + char *a[] = { "sip", "show", "peers" }; + int ret; + int type = 0; /* Default format */ + if (format) { + if (strstr(format, "text/xml")) + type=1; /* Client accepts XML */ + } + + + ast_mutex_lock(&s->lock); + ast_cli(s->fd, "Response: Success\r\n"); + if (id && !ast_strlen_zero(id)) + ast_cli(s->fd, "ActionID: %s\r\n",id); + ret = _sip_show_peers(type, s->fd, s, m, 3, a ); + ast_cli( s->fd, "\r\n\r\n" ); + ast_mutex_unlock(&s->lock); + return ret; +} + /*--- sip_show_peers: CLI Show Peers command */ static int sip_show_peers(int fd, int argc, char *argv[]) { + return _sip_show_peers(0, fd, NULL, NULL, argc, argv); +} + +/*--- sip_show_xpeers: CLI Show Peers command */ +static int sip_xshow_peers(int fd, int argc, char *argv[]) +{ + return _sip_show_peers(1, fd, NULL, NULL, argc, argv); +} + +/*--- _sip_show_peers: Execute sip show peers and xshow commands */ +static int _sip_show_peers(int type, int fd, struct mansession *s, struct message *m, int argc, char *argv[]) +{ regex_t regexbuf; int havepattern = 0; #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-15.15s %-8s %-10s\n" #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-15.15s %-8d %-10s\n" +#define FORMATXML "%s%s%d%s%s%s%s/>\n" char name[256] = ""; char iabuf[INET_ADDRSTRLEN]; @@ -6076,7 +6162,11 @@ havepattern = 1; } - ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Mask", "Port", "Status"); + if (type == 0) { /* Normal list */ + ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Mask", "Port", "Status"); + } else { + ast_cli(fd, "\n\n", havepattern?"on":"off"); + } ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { char nm[20] = ""; @@ -6091,7 +6181,7 @@ } ast_inet_ntoa(nm, sizeof(nm), iterator->mask); - if (!ast_strlen_zero(iterator->username)) + if (!ast_strlen_zero(iterator->username) && type==0) snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); else strncpy(name, iterator->name, sizeof(name) - 1); @@ -6131,20 +6221,36 @@ iterator->ha ? " A " : " ", /* permit/deny */ nm, ntohs(iterator->addr.sin_port), status); - ast_cli(fd, FORMAT, name, + if (type == 0) {/* Normal CLI list */ + ast_cli(fd, FORMAT, name, iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", ast_test_flag(iterator, SIP_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ iterator->ha ? " A " : " ", /* permit/deny */ nm, ntohs(iterator->addr.sin_port), status); + } else { /* XML format */ + ast_cli(fd, FORMATXML, + iterator->name, + iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", + ntohs(iterator->addr.sin_port), + ast_test_flag(iterator, SIP_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ + (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ + iterator->ha ? "yes" : "no", /* permit/deny */ + status); + + } ASTOBJ_UNLOCK(iterator); total_peers++; } while(0) ); - ast_cli(fd,"%d sip peers [%d online , %d offline]\n",total_peers,peers_online,peers_offline); + if (type==0) { + ast_cli(fd,"%d sip peers [%d online , %d offline]\n",total_peers,peers_online,peers_offline); + } else { + ast_cli(fd,"\n"); + } if (havepattern) regfree(®exbuf); @@ -6228,9 +6334,67 @@ return RESULT_SUCCESS; } +static char mandescr_show_peer[] = +"Description: Show one SIP peer with details on current status.\n" +" The XML format is under development, feedback welcome! /oej\n" +"Variables: \n" +" Peer: The peer name you want to check.\n" +" ActionID: Optional action ID for this AMI transaction.\n" +" Accept: text/xml Indicates that we can send the listing in XML format.\n" +" Accept: text/plain The default format (as in the CLI.)\n"; + +static int _sip_show_peer(int type, int fd, struct mansession *s, struct message *m, int argc, char *argv[]); + +/*--- manager_sip_show_peer: Show SIP peers in the manager API ---*/ +static int manager_sip_show_peer( struct mansession *s, struct message *m ) +{ + char *id = astman_get_header(m,"ActionID"); + char *format = astman_get_header(m, "Accept"); + char *a[4]; + char *peer; + int ret; + int type = 0; + + peer = astman_get_header(m,"Peer"); + if (!peer || ast_strlen_zero(peer)) { + astman_send_error(s, m, "Peer: missing.\n"); + return 0; + } + ast_mutex_lock(&s->lock); + a[0] = "sip"; + a[1] = "show"; + a[2] = "peer"; + a[3] = peer; + + if (format) { + if (strstr(format, "text/xml")) + type=1; /* Client accepts XML */ + } + + if (id && !ast_strlen_zero(id)) + ast_cli(s->fd, "ActionID: %s\r\n",id); + ret = _sip_show_peer(1, s->fd, s, m, 4, a ); + ast_cli( s->fd, "\r\n\r\n" ); + ast_mutex_unlock(&s->lock); + return ret; +} + + + +/*--- sip_xshow_peer: Show one peer in detail ---*/ +static int sip_xshow_peer(int fd, int argc, char *argv[]) +{ + return _sip_show_peer(1, fd, NULL, NULL, argc, argv); +} + /*--- sip_show_peer: Show one peer in detail ---*/ static int sip_show_peer(int fd, int argc, char *argv[]) { + return _sip_show_peer(0, fd, NULL, NULL, argc, argv); +} + +static int _sip_show_peer(int type, int fd, struct mansession *s, struct message *m, int argc, char *argv[]) +{ char status[30] = ""; char cbuf[256]; char iabuf[INET_ADDRSTRLEN]; @@ -6247,7 +6411,16 @@ load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; peer = find_peer(argv[3], NULL, load_realtime); - if (peer) { + if (s) { /* Manager */ + if (peer) + ast_cli(s->fd, "Response: Success\r\n"); + else { + snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]); + astman_send_error(s, m, cbuf); + return 0; + } + } + if (peer && type==0 ) { /* Normal listing */ ast_cli(fd,"\n\n"); ast_cli(fd, " * Name : %s\n", peer->name); ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"":""); @@ -6317,7 +6490,7 @@ strncpy(status, "UNKNOWN", sizeof(status) - 1); ast_cli(fd, "%s\n",status); ast_cli(fd, " Useragent : %s\n", peer->useragent); - ast_cli(fd, " Full Contact : %s\n", peer->fullcontact); + ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); if (peer->chanvars) { ast_cli(fd, " Variables :\n"); for (v = peer->chanvars ; v ; v = v->next) @@ -6325,6 +6498,82 @@ } ast_cli(fd,"\n"); ASTOBJ_UNREF(peer,sip_destroy_peer); + } else if (peer && type == 1) { /* XML listing */ + ast_cli(fd,"\n"); + ast_cli(fd,"\n"); + ast_cli(fd,"\n"); + ast_cli(fd, "\n%s\n", peer->name); + ast_cli(fd, "%smd5\n", ast_strlen_zero(peer->secret)?"no":"yes"); + ast_cli(fd, "%s\n", ast_strlen_zero(peer->md5secret)?"no":"yes"); + ast_cli(fd, "%s\n", peer->context); + ast_cli(fd, "%s\n", peer->language); + ast_cli(fd, "%s\n", peer->accountcode); + ast_cli(fd, "%s\n", ast_cdr_flags2str(peer->amaflags)); + ast_cli(fd, "%s\n", peer->fromuser); + ast_cli(fd, "%s\n", peer->fromdomain); + ast_cli(fd, ""); + print_group(fd, peer->callgroup); + ast_cli(fd, "\n"); + ast_cli(fd, ""); + print_group(fd, peer->pickupgroup); + ast_cli(fd, ""); + ast_cli(fd, "%s\n", peer->mailbox); + ast_cli(fd, "%d\n", peer->lastmsgssent); + ast_cli(fd, "%d\n", peer->lastmsg); + ast_cli(fd, "%d\n", peer->incominglimit); + ast_cli(fd, "%d\n", peer->outgoinglimit); + ast_cli(fd, "%s\n", (ast_test_flag(peer, SIP_DYNAMIC)?"yes":"no")); + ast_cli(fd, "%s%s%d\n", peer->cid_name, peer->cid_num, peer->callingpres); + ast_cli(fd, "%d\n", peer->expire); + ast_cli(fd, "%d\n", peer->expiry); + ast_cli(fd, "%s\n", insecure2str(ast_test_flag(peer, SIP_INSECURE))); + ast_cli(fd, "%s\n", nat2str(ast_test_flag(peer, SIP_NAT))); + ast_cli(fd, "%s\n", (peer->ha?"yes":"no")); + ast_cli(fd, "%s\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"yes":"no")); + ast_cli(fd, "%s\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"yes":"no")); + ast_cli(fd, "%s\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"yes":"no")); + /* - is enumerated */ + ast_cli(fd, "%s\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF))); + ast_cli(fd, "%s\n", peer->tohost); + ast_cli(fd, "%s%d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", ntohs(peer->addr.sin_port)); + ast_cli(fd, "%s%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); + ast_cli(fd, "%s\n", peer->username); + ast_cli(fd, ""); + ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); + ast_cli(fd, "%s\n", codec_buf); + ast_cli(fd, ""); + pref = &peer->prefs; + for(x = 0; x < 32 ; x++) { + codec = ast_codec_pref_index(pref,x); + if(!codec) + break; + ast_cli(fd, "%s", ast_getformatname(codec)); + if(x < 31 && ast_codec_pref_index(pref,x+1)) + ast_cli(fd, ","); + } + ast_cli(fd, ""); + + ast_cli(fd, ""); + if (peer->lastms < 0) + strncpy(status, "UNREACHABLE", sizeof(status) - 1); + else if (peer->lastms > peer->maxms) + snprintf(status, sizeof(status), "LAGGED (%d ms)", peer->lastms); + else if (peer->lastms) + snprintf(status, sizeof(status), "OK (%d ms)", peer->lastms); + else + strncpy(status, "UNKNOWN", sizeof(status) - 1); + ast_cli(fd, "%s\n",status); + ast_cli(fd, "%s\n", peer->useragent); + ast_cli(fd, "%s\n", peer->fullcontact); + if (peer->chanvars) { + ast_cli(fd, "\n"); + for (v = peer->chanvars ; v ; v = v->next) + ast_cli(fd, " %s%s\n", v->name, v->value); + ast_cli(fd, "\n"); + } + ast_cli(fd,"\n\n"); + ASTOBJ_UNREF(peer,sip_destroy_peer); + } else { ast_cli(fd,"Peer %s not found.\n", argv[3]); ast_cli(fd,"\n"); @@ -7164,6 +7413,16 @@ " Lists all known SIP peers.\n" " Optional regular expression pattern is used to filter the peer list.\n"; +static char xshow_peers_usage[] = +"Usage: sip xshow peers [pattern]\n" +" Lists all known SIP peers in XML format.\n" +" Optional regular expression pattern is used to filter the peer list.\n"; + +static char xshow_peer_usage[] = +"Usage: sip xshow peer [load]\n" +" Lists all details on one SIP peer and the current status in XML format.\n" +" Option \"load\" forces lookup of peer in realtime storage.\n"; + static char show_peer_usage[] = "Usage: sip show peer [load]\n" " Lists all details on one SIP peer and the current status.\n" @@ -7234,8 +7493,12 @@ { { "sip", "debug", "ip", NULL }, sip_do_debug, "Enable SIP debugging on IP", debug_usage }; static struct ast_cli_entry cli_debug_peer = { { "sip", "debug", "peer", NULL }, sip_do_debug, "Enable SIP debugging on Peername", debug_usage, complete_sip_debug_peer }; +static struct ast_cli_entry cli_xshow_peer = + { { "sip", "xshow", "peer", NULL }, sip_xshow_peer, "Show details on specific SIP peer (XML format)", xshow_peer_usage, complete_sip_show_peer }; static struct ast_cli_entry cli_show_peer = { { "sip", "show", "peer", NULL }, sip_show_peer, "Show details on specific SIP peer", show_peer_usage, complete_sip_show_peer }; +static struct ast_cli_entry cli_xshow_peers = + { { "sip", "xshow", "peers", NULL }, sip_xshow_peers, "List defined SIP peers in XML format", xshow_peers_usage }; static struct ast_cli_entry cli_show_peers = { { "sip", "show", "peers", NULL }, sip_show_peers, "Show defined SIP peers", show_peers_usage }; static struct ast_cli_entry cli_prune_realtime = @@ -7888,6 +8151,7 @@ int respid; int res; int gotdest; + int i; char iabuf[INET_ADDRSTRLEN]; struct ast_frame af = { AST_FRAME_NULL, }; int debug = sip_debug_test_pvt(p); @@ -7909,18 +8173,27 @@ /* Determine the request URI for sip, sips or tel URIs */ if( determine_firstline_parts( req ) < 0 ) { - return -1; + return -1; } - cmd= req->rlPart1; - e= req->rlPart2; + cmd = req->rlPart1; + e = req->rlPart2; /* Save useragent of the client */ useragent = get_header(req, "User-Agent"); strncpy(p->useragent, useragent, sizeof(p->useragent)-1); + /* Find out SIP method */ if (strcasecmp(cmd, "SIP/2.0")) { + /* Request coming in */ + for (i=0; i< SIP_MAX_METHODS; i++) { + if (!strcasecmp(sip_methods[i].method, cmd)) { + p->method = sip_methods[i].id; + if (option_debug > 2) + ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[i].method, sip_methods[i].id, cmd); + } + } if (p->icseq && (p->icseq > seqno)) { ast_log(LOG_DEBUG, "Ignoring too old packet packet %d (expecting >= %d)\n", seqno, p->icseq); return -1; @@ -7930,6 +8203,7 @@ the last sequence number */ ignore=1; } + if (ast_strlen_zero(p->theirtag)) { from = get_header(req, "From"); from = strstr(from, "tag="); @@ -7943,6 +8217,7 @@ } snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); } else { + p->method = SIP_RESPONSE; /* Response to our request -- Do some sanity checks */ if (!p->initreq.headers) { ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about.\n"); @@ -7958,14 +8233,15 @@ } } - if (strcmp(cmd, "SIP/2.0") && (seqno >= p->icseq)) + if (p->method == SIP_RESPONSE && (seqno >= p->icseq)) /* Next should follow monotonically (but not necessarily incrementally -- thanks again to the genius authors of SIP -- increasing */ p->icseq = seqno; /* Initialize the context if it hasn't been already */ - if (!strcasecmp(cmd, "OPTIONS")) { + if (p->method == SIP_OPTIONS) { + //if (!strcasecmp(cmd, "OPTIONS")) { res = get_destination(p, req); build_contact(p); /* XXX Should we authenticate OPTIONS? XXX */ @@ -7981,7 +8257,8 @@ it's in the middle of a normal call flow. */ if (!p->lastinvite) ast_set_flag(p, SIP_NEEDDESTROY); - } else if (!strcasecmp(cmd, "INVITE")) { + //} else if (!strcasecmp(cmd, "INVITE")) { + } else if (p->method == SIP_INVITE) { if (ast_test_flag(p, SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { /* This is a call to ourself. Send ourselves an error code and stop processing immediately, as SIP really has no good mechanism for @@ -8146,9 +8423,9 @@ if (p && !ast_test_flag(p, SIP_NEEDDESTROY)) { if (!p->jointcapability) { if (ignore) - transmit_response(p, "488 Not Acceptable Here", req); + transmit_response(p, "488 Not Acceptable Here (codec error)", req); else - transmit_response_reliable(p, "488 Not Acceptable Here", req, 1); + transmit_response_reliable(p, "488 Not Acceptable Here (codec error)", req, 1); ast_set_flag(p, SIP_NEEDDESTROY); } else { ast_log(LOG_NOTICE, "Unable to create/find channel\n"); @@ -8160,8 +8437,10 @@ } } } - } else if (!strcasecmp(cmd, "REFER")) { - ast_log(LOG_DEBUG, "We found a REFER!\n"); + //} else if (!strcasecmp(cmd, "REFER")) { + } else if (p->method == SIP_REFER) { + if (option_debug > 2) + ast_log(LOG_DEBUG, "We found a REFER!\n"); if (ast_strlen_zero(p->context)) strncpy(p->context, default_context, sizeof(p->context) - 1); res = get_refer_info(p, req); @@ -8218,7 +8497,8 @@ } } } - } else if (!strcasecmp(cmd, "CANCEL")) { + //} else if (!strcasecmp(cmd, "CANCEL")) { + } else if (p->method == SIP_CANCEL) { check_via(p, req); ast_set_flag(p, SIP_ALREADYGONE); if (p->rtp) { @@ -8240,7 +8520,8 @@ } else { transmit_response(p, "481 Call Leg Does Not Exist", req); } - } else if (!strcasecmp(cmd, "BYE")) { + //} else if (!strcasecmp(cmd, "BYE")) { + } else if (p->method == SIP_BYE) { copy_request(&p->initreq, req); check_via(p, req); ast_set_flag(p, SIP_ALREADYGONE); @@ -8394,7 +8675,8 @@ sip_scheddestroy(p, (p->expiry+10)*1000); transmit_state_notify(p, ast_extension_state(NULL, p->context, p->exten),1); } - } else if (!strcasecmp(cmd, "INFO")) { + //} else if (!strcasecmp(cmd, "INFO")) { + } else if (p->method == SIP_INFO) { if (!ignore) { if (debug) ast_verbose("Receiving DTMF!\n"); @@ -8402,13 +8684,15 @@ } else { /* if ignoring, transmit response */ transmit_response(p, "200 OK", req); } - } else if (!strcasecmp(cmd, "NOTIFY")) { + //} else if (!strcasecmp(cmd, "NOTIFY")) { + } else if (p->method == SIP_NOTIFY) { /* XXX we get NOTIFY's from some servers. WHY?? Maybe we should look into this someday XXX */ transmit_response(p, "200 OK", req); if (!p->lastinvite) ast_set_flag(p, SIP_NEEDDESTROY); - } else if (!strcasecmp(cmd, "REGISTER")) { + //} else if (!strcasecmp(cmd, "REGISTER")) { + } else if (p->method == SIP_REGISTER) { /* Use this as the basis */ if (debug) ast_verbose("Using latest request as basis request\n"); @@ -8428,9 +8712,10 @@ } /* Destroy the session, but keep us around for just a bit in case they don't get our 200 OK */ - sip_scheddestroy(p, 15*1000); + sip_scheddestroy(p, 15*1000); } - } else if (!strcasecmp(cmd, "ACK")) { + //} else if (!strcasecmp(cmd, "ACK")) { + } else if (p->method == SIP_ACK) { /* Make sure we don't ignore this */ if (seqno == p->pendinginvite) { p->pendinginvite = 0; @@ -8443,7 +8728,8 @@ } if (!p->lastinvite && ast_strlen_zero(p->randdata)) ast_set_flag(p, SIP_NEEDDESTROY); - } else if (!strcasecmp(cmd, "SIP/2.0")) { + //} else if (!strcasecmp(cmd, "SIP/2.0")) { + } else if (p->method == SIP_RESPONSE) { extract_uri(p, req); while(*e && (*e < 33)) e++; if (sscanf(e, "%i %n", &respid, &len) != 1) { @@ -10131,6 +10417,7 @@ return 0; } +/*--- reload: Part of Asterisk module interface ---*/ int reload(void) { return sip_reload(0, 0, NULL); @@ -10175,6 +10462,8 @@ ast_cli_register(&cli_prune_realtime); ast_cli_register(&cli_show_peer); ast_cli_register(&cli_show_peers); + ast_cli_register(&cli_xshow_peer); + ast_cli_register(&cli_xshow_peers); ast_cli_register(&cli_show_registry); ast_cli_register(&cli_debug); ast_cli_register(&cli_debug_ip); @@ -10184,6 +10473,8 @@ ast_cli_register(&cli_no_history); ast_cli_register(&cli_sip_reload); ast_cli_register(&cli_inuse_show); + ast_manager_register2( "SIPpeers", 0, manager_sip_show_peers, "List SIP Peers (text or XML)", mandescr_show_peers ); + ast_manager_register2( "SIPshowpeer", 0, manager_sip_show_peer, "Show SIP Peer (text or XML)", mandescr_show_peer ); sip_rtp.type = channeltype; ast_rtp_proto_register(&sip_rtp); ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); @@ -10216,6 +10507,8 @@ ast_cli_unregister(&cli_prune_realtime); ast_cli_unregister(&cli_show_peer); ast_cli_unregister(&cli_show_peers); + ast_cli_unregister(&cli_xshow_peers); + ast_cli_unregister(&cli_xshow_peer); ast_cli_unregister(&cli_show_registry); ast_cli_unregister(&cli_show_subscriptions); ast_cli_unregister(&cli_debug); @@ -10228,6 +10521,8 @@ ast_cli_unregister(&cli_inuse_show); ast_rtp_proto_unregister(&sip_rtp); ast_channel_unregister(channeltype); + ast_manager_unregister("SIPpeers"); + ast_manager_unregister("SIPshowpeer"); if (!ast_mutex_lock(&iflock)) { /* Hangup all interfaces if they have an owner */ p = iflist;