![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
sip3_cliami.c
Go to the documentation of this file.
00001 /* 00002 * Asterisk -- An open source telephony toolkit. 00003 * 00004 * Copyright (C) 1999 - 2007, Digium, Inc. 00005 * and Edvina AB, Sollentuna, Sweden (chan_sip3 changes/additions) 00006 * 00007 * Mark Spencer <markster@digium.com> 00008 * 00009 * See http://www.asterisk.org for more information about 00010 * the Asterisk project. Please do not directly contact 00011 * any of the maintainers of this project for assistance; 00012 * the project provides a web site, mailing lists and IRC 00013 * channels for your use. 00014 * 00015 * This program is free software, distributed under the terms of 00016 * the GNU General Public License Version 2. See the LICENSE file 00017 * at the top of the source tree. 00018 */ 00019 00020 /*! 00021 * \file 00022 * \brief SIP CLI and manager commands 00023 * Version 3 of chan_sip 00024 * 00025 * \author Mark Spencer <markster@digium.com> 00026 * \author Olle E. Johansson <oej@edvina.net> (all the chan_sip3 changes) 00027 * 00028 * See Also: 00029 * \arg \ref AstCREDITS 00030 * 00031 */ 00032 00033 #include "asterisk.h" 00034 00035 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 53128 $") 00036 00037 #include <stdio.h> 00038 #include <ctype.h> 00039 #include <string.h> 00040 #include <unistd.h> 00041 #include <sys/socket.h> 00042 #include <sys/ioctl.h> 00043 #include <net/if.h> 00044 #include <errno.h> 00045 #include <stdlib.h> 00046 #include <fcntl.h> 00047 #include <netdb.h> 00048 #include <signal.h> 00049 #include <sys/signal.h> 00050 #include <netinet/in.h> 00051 #include <netinet/in_systm.h> 00052 #include <arpa/inet.h> 00053 #include <netinet/ip.h> 00054 #include <regex.h> 00055 00056 #include "asterisk/cli.h" 00057 #include "asterisk/lock.h" 00058 #include "asterisk/channel.h" 00059 #include "asterisk/config.h" 00060 #include "asterisk/logger.h" 00061 #include "asterisk/module.h" 00062 #include "asterisk/pbx.h" 00063 #include "asterisk/options.h" 00064 #include "asterisk/sched.h" 00065 #include "asterisk/io.h" 00066 #include "asterisk/rtp.h" 00067 #include "asterisk/udptl.h" 00068 #include "asterisk/acl.h" 00069 #include "asterisk/manager.h" 00070 #include "asterisk/callerid.h" 00071 #include "asterisk/cli.h" 00072 #include "asterisk/app.h" 00073 #include "asterisk/musiconhold.h" 00074 #include "asterisk/features.h" 00075 //#include "asterisk/srv.h" 00076 //#include "asterisk/astdb.h" 00077 #include "asterisk/causes.h" 00078 #include "asterisk/utils.h" 00079 #include "asterisk/file.h" 00080 #include "asterisk/astobj.h" 00081 #include "asterisk/dnsmgr.h" 00082 #include "asterisk/devicestate.h" 00083 #include "asterisk/linkedlists.h" 00084 #include "asterisk/stringfields.h" 00085 #include "asterisk/monitor.h" 00086 #include "asterisk/localtime.h" 00087 #include "asterisk/abstract_jb.h" 00088 #include "asterisk/compiler.h" 00089 #include "sip3.h" 00090 #include "sip3funcs.h" 00091 00092 00093 /*! \brief Display SIP nat mode */ 00094 const char *sip_nat_mode(const struct sip_dialog *p) 00095 { 00096 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT"; 00097 } 00098 00099 /*! \brief Convert transfer mode to text string */ 00100 static char *transfermode2str(enum transfermodes mode) 00101 { 00102 if (mode == TRANSFER_OPENFORALL) 00103 return "open"; 00104 else if (mode == TRANSFER_CLOSED) 00105 return "closed"; 00106 return "strict"; 00107 } 00108 00109 /*! \brief Convert NAT setting to text string */ 00110 static char *nat2str(int nat) 00111 { 00112 switch(nat) { 00113 case SIP_NAT_NEVER: 00114 return "No"; 00115 case SIP_NAT_ROUTE: 00116 return "Route"; 00117 case SIP_NAT_ALWAYS: 00118 return "Always"; 00119 case SIP_NAT_RFC3581: 00120 return "RFC3581"; 00121 default: 00122 return "Unknown"; 00123 } 00124 } 00125 00126 /*! \brief Convert DTMF mode to printable string */ 00127 static const char *dtmfmode2str(int mode) 00128 { 00129 switch (mode) { 00130 case SIP_DTMF_RFC2833: 00131 return "rfc2833"; 00132 case SIP_DTMF_INFO: 00133 return "info"; 00134 case SIP_DTMF_INBAND: 00135 return "inband"; 00136 case SIP_DTMF_AUTO: 00137 return "auto"; 00138 } 00139 return "<error>"; 00140 } 00141 00142 /*! \brief Convert Insecure setting to printable string */ 00143 static const char *insecure2str(int port, int invite) 00144 { 00145 if (port && invite) 00146 return "port,invite"; 00147 else if (port) 00148 return "port"; 00149 else if (invite) 00150 return "invite"; 00151 else 00152 return "no"; 00153 } 00154 00155 /*! \brief Print codec list from preference to CLI/manager */ 00156 static void print_codec_to_cli(int fd, struct ast_codec_pref *pref) 00157 { 00158 int x, codec; 00159 00160 for(x = 0; x < 32 ; x++) { 00161 codec = ast_codec_pref_index(pref, x); 00162 if (!codec) 00163 break; 00164 ast_cli(fd, "%s", ast_getformatname(codec)); 00165 ast_cli(fd, ":%d", pref->framing[x]); 00166 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 00167 ast_cli(fd, ","); 00168 } 00169 if (!x) 00170 ast_cli(fd, "none"); 00171 } 00172 00173 /*! \brief Print call group and pickup group */ 00174 void print_group(int fd, ast_group_t group, int crlf) 00175 { 00176 char buf[256]; 00177 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 00178 } 00179 00180 /*! \brief Report Device status in character string 00181 * \return 0 if peer is unreachable, 1 if peer is online, -1 if unmonitored 00182 */ 00183 int device_status(struct sip_device *device, char *status, int statuslen) 00184 { 00185 int res = 0; 00186 if (device->maxms) { 00187 if (device->lastms < 0) { 00188 ast_copy_string(status, "UNREACHABLE", statuslen); 00189 } else if (device->lastms > device->maxms) { 00190 snprintf(status, statuslen, "LAGGED (%d ms)", device->lastms); 00191 res = 1; 00192 } else if (device->lastms) { 00193 snprintf(status, statuslen, "OK (%d ms)", device->lastms); 00194 res = 1; 00195 } else { 00196 ast_copy_string(status, "UNKNOWN", statuslen); 00197 } 00198 } else { 00199 ast_copy_string(status, "Unmonitored", statuslen); 00200 /* Checking if port is 0 */ 00201 res = -1; 00202 } 00203 return res; 00204 } 00205 00206 /*! \brief CLI Command to show calls within limits set by call_limit */ 00207 static int sip_show_inuse(int fd, int argc, char *argv[]) 00208 { 00209 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 00210 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 00211 char ilimits[40]; 00212 char iused[40]; 00213 int showall = FALSE; 00214 00215 if (argc < 3) 00216 return RESULT_SHOWUSAGE; 00217 00218 if (argc == 4 && !strcmp(argv[3],"all")) 00219 showall = TRUE; 00220 00221 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 00222 00223 ASTOBJ_CONTAINER_TRAVERSE(&devicelist, 1, do { 00224 ASTOBJ_RDLOCK(iterator); 00225 if (iterator->call_limit) 00226 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 00227 else 00228 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 00229 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 00230 if (showall || iterator->call_limit) 00231 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 00232 ASTOBJ_UNLOCK(iterator); 00233 } while (0) ); 00234 00235 return RESULT_SUCCESS; 00236 #undef FORMAT 00237 #undef FORMAT2 00238 } 00239 00240 char mandescr_show_devices[] = 00241 "Description: Lists SIP peers in text format with details on current status.\n" 00242 "Variables: \n" 00243 " ActionID: <id> Action ID for this transaction. Will be returned.\n"; 00244 00245 /*! \brief Execute sip show devices command */ 00246 static int _sip_show_devices(int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[]) 00247 { 00248 regex_t regexbuf; 00249 int havepattern = FALSE; 00250 00251 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 00252 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 00253 00254 char name[256]; 00255 int total_peers = 0; 00256 int peers_mon_online = 0; 00257 int peers_mon_offline = 0; 00258 int peers_unmon_offline = 0; 00259 int peers_unmon_online = 0; 00260 const char *id; 00261 char idtext[256] = ""; 00262 int realtimepeers; 00263 00264 realtimepeers = ast_check_realtime("sippeers"); 00265 00266 if (s) { /* Manager - get ActionID */ 00267 id = astman_get_header(m, "ActionID"); 00268 if (!ast_strlen_zero(id)) 00269 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 00270 } 00271 00272 switch (argc) { 00273 case 5: 00274 if (!strcasecmp(argv[3], "like")) { 00275 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 00276 return RESULT_SHOWUSAGE; 00277 havepattern = TRUE; 00278 } else 00279 return RESULT_SHOWUSAGE; 00280 case 3: 00281 break; 00282 default: 00283 return RESULT_SHOWUSAGE; 00284 } 00285 00286 if (!s) /* Normal list */ 00287 ast_cli(fd, FORMAT2, "Name", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 00288 00289 ASTOBJ_CONTAINER_TRAVERSE(&devicelist, 1, do { 00290 char status[20] = ""; 00291 char srch[2000]; 00292 char pstatus; 00293 00294 ASTOBJ_RDLOCK(iterator); 00295 00296 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 00297 ASTOBJ_UNLOCK(iterator); 00298 continue; 00299 } 00300 00301 if (!ast_strlen_zero(iterator->domain) && !s) 00302 snprintf(name, sizeof(name), "%s@%s", iterator->name, iterator->domain); 00303 else 00304 ast_copy_string(name, iterator->name, sizeof(name)); 00305 00306 pstatus = device_status(iterator, status, sizeof(status)); 00307 if (pstatus == 1) 00308 peers_mon_online++; 00309 else if (pstatus == 0) 00310 peers_mon_offline++; 00311 else { 00312 if (iterator->addr.sin_port == 0) 00313 peers_unmon_offline++; 00314 else 00315 peers_unmon_online++; 00316 } 00317 00318 snprintf(srch, sizeof(srch), FORMAT, name, 00319 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 00320 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 00321 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 00322 iterator->ha ? " A " : " ", /* permit/deny */ 00323 ntohs(iterator->addr.sin_port), status, 00324 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 00325 00326 if (!s) {/* Normal CLI list */ 00327 ast_cli(fd, FORMAT, name, 00328 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 00329 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 00330 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 00331 iterator->ha ? " A " : " ", /* permit/deny */ 00332 00333 ntohs(iterator->addr.sin_port), status, 00334 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 00335 } else { /* Manager format */ 00336 /* The names here need to be the same as other channels */ 00337 astman_append(s, 00338 "Event: PeerEntry\r\n%s" 00339 "Channeltype: SIP\r\n" 00340 "ObjectName: %s\r\n" 00341 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 00342 "IPaddress: %s\r\n" 00343 "IPport: %d\r\n" 00344 "Dynamic: %s\r\n" 00345 "Natsupport: %s\r\n" 00346 "VideoSupport: %s\r\n" 00347 "ACL: %s\r\n" 00348 "Status: %s\r\n" 00349 "RealtimeDevice: %s\r\n\r\n", 00350 idtext, 00351 iterator->name, 00352 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 00353 ntohs(iterator->addr.sin_port), 00354 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 00355 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 00356 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 00357 iterator->ha ? "yes" : "no", /* permit/deny */ 00358 status, 00359 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 00360 } 00361 00362 ASTOBJ_UNLOCK(iterator); 00363 00364 total_peers++; 00365 } while(0) ); 00366 00367 if (!s) 00368 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 00369 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 00370 00371 if (havepattern) 00372 regfree(®exbuf); 00373 00374 if (total) 00375 *total = total_peers; 00376 00377 00378 return RESULT_SUCCESS; 00379 #undef FORMAT 00380 #undef FORMAT2 00381 } 00382 00383 /*! \brief Show SIP peers in the manager API */ 00384 /* Inspired from chan_iax2 */ 00385 int manager_sip_show_devices(struct mansession *s, const struct message *m ) 00386 { 00387 const char *id = astman_get_header(m,"ActionID"); 00388 const char *a[] = { "sip3", "show", "peers" }; 00389 char idtext[256] = ""; 00390 int total = 0; 00391 00392 if (!ast_strlen_zero(id)) 00393 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 00394 00395 astman_send_ack(s, m, "Peer status list will follow"); 00396 /* List the peers in separate manager events */ 00397 _sip_show_devices(-1, &total, s, m, 3, a); 00398 /* Send final confirmation */ 00399 astman_append(s, 00400 "Event: PeerlistComplete\r\n" 00401 "ListItems: %d\r\n" 00402 "%s" 00403 "\r\n", total, idtext); 00404 return 0; 00405 } 00406 00407 00408 /*! \brief CLI Show Peers command */ 00409 static int sip_show_devices(int fd, int argc, char *argv[]) 00410 { 00411 return _sip_show_devices(fd, NULL, NULL, NULL, argc, (const char **) argv); 00412 } 00413 00414 00415 /*! \brief List all allocated SIP Objects (realtime or static) */ 00416 static int sip_show_objects(int fd, int argc, char *argv[]) 00417 { 00418 char tmp[256]; 00419 if (argc != 3) 00420 return RESULT_SHOWUSAGE; 00421 ast_cli(fd, "-= Device objects: %d static, %d realtime, %d autocreate =-\n\n", sipcounters.static_peers, sipcounters.realtime_peers, sipcounters.autocreated_peers); 00422 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &devicelist); 00423 ast_cli(fd, "-= Registry objects: %d =-\n\n", sipcounters.registry_objects); 00424 ast_cli(fd, "-= Dialog objects: %d =-\n\n", sipcounters.dialog_objects); 00425 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 00426 return RESULT_SUCCESS; 00427 } 00428 00429 static char mandescr_show_device[] = 00430 "Description: Show one SIP device with details on current status.\n" 00431 "Variables: \n" 00432 " Peer: <name> The peer name you want to check.\n" 00433 " ActionID: <id> Optional action ID for this AMI transaction.\n"; 00434 00435 /*! \brief Show one peer in detail (main function) */ 00436 static int _sip_show_device(int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]) 00437 { 00438 char status[30] = ""; 00439 char cbuf[256]; 00440 struct sip_device *device; 00441 char codec_buf[512]; 00442 struct ast_codec_pref *pref; 00443 struct ast_variable *v; 00444 struct sip_auth *auth; 00445 int x = 0, codec = 0, load_realtime; 00446 int realtimepeers; 00447 00448 realtimepeers = ast_check_realtime("sippeers"); 00449 00450 if (argc < 4) 00451 return RESULT_SHOWUSAGE; 00452 00453 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 00454 device = find_device(argv[3], NULL, load_realtime); 00455 if (s) { /* Manager */ 00456 if (device) 00457 astman_append(s, "Response: Success\r\n"); 00458 else { 00459 snprintf (cbuf, sizeof(cbuf), "Device %s not found.\n", argv[3]); 00460 astman_send_error(s, m, cbuf); 00461 return 0; 00462 } 00463 } 00464 if (device && type==0 ) { /* Normal listing */ 00465 ast_cli(fd,"\n\n"); 00466 if (!ast_strlen_zero(device->domain)) 00467 ast_cli(fd, " * Name : %s@%s\n", device->name, device->domain); 00468 else 00469 ast_cli(fd, " * Name : %s <no domain>\n", device->name); 00470 if (realtimepeers) { /* Realtime is enabled */ 00471 ast_cli(fd, " Realtime device: %s\n", ast_test_flag(&device->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 00472 } 00473 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(device->secret)?"<Not set>":"<Set>"); 00474 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(device->md5secret)?"<Not set>":"<Set>"); 00475 for (auth = device->auth; auth; auth = auth->next) { 00476 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 00477 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 00478 } 00479 ast_cli(fd, " Context : %s\n", device->extra.context); 00480 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(device->extra.subscribecontext, "<Not set>") ); 00481 ast_cli(fd, " Language : %s\n", device->language); 00482 if (!ast_strlen_zero(device->extra.accountcode)) 00483 ast_cli(fd, " Accountcode : %s\n", device->extra.accountcode); 00484 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(device->extra.amaflags)); 00485 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(device->allowtransfer)); 00486 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(device->callingpres)); 00487 if (!ast_strlen_zero(device->extra.fromuser)) 00488 ast_cli(fd, " FromUser : %s\n", device->extra.fromuser); 00489 if (!ast_strlen_zero(device->extra.fromdomain)) 00490 ast_cli(fd, " FromDomain : %s\n", device->extra.fromdomain); 00491 ast_cli(fd, " Callgroup : "); 00492 print_group(fd, device->callgroup, 0); 00493 ast_cli(fd, " Pickupgroup : "); 00494 print_group(fd, device->pickupgroup, 0); 00495 ast_cli(fd, " Mailbox : %s\n", device->mailbox.mailbox); 00496 ast_cli(fd, " VM Extension : %s\n", device->mailbox.vmexten); 00497 ast_cli(fd, " Call limit : %d\n", device->call_limit); 00498 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&device->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 00499 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, device->expire)); 00500 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), device->extra.cid_name, device->extra.cid_num, "<unspecified>")); 00501 if (!ast_strlen_zero(global.regcontext)) 00502 ast_cli(fd, " Reg. exten : %s\n", device->extra.regexten); 00503 ast_cli(fd, " MaxCallBR : %d kbps\n", device->maxcallbitrate); 00504 ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(&device->flags[0], SIP_INSECURE_PORT), ast_test_flag(&device->flags[0], SIP_INSECURE_INVITE))); 00505 ast_cli(fd, " Nat support : %s\n", nat2str(ast_test_flag(&device->flags[0], SIP_NAT))); 00506 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&device->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 00507 ast_cli(fd, " ACL : %s\n", (device->ha?"Yes":"No")); 00508 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&device->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 00509 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&device->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 00510 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&device->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 00511 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&device->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 00512 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&device->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 00513 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&device->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 00514 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&device->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 00515 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&device->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 00516 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&device->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 00517 00518 /* - is enumerated */ 00519 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&device->flags[0], SIP_DTMF))); 00520 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&device->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 00521 ast_cli(fd, " ToHost : %s\n", device->extra.tohost); 00522 ast_cli(fd, " Addr->IP : %s Port %d\n", device->addr.sin_addr.s_addr ? ast_inet_ntoa(device->addr.sin_addr) : "(Unspecified)", ntohs(device->addr.sin_port)); 00523 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(device->defaddr.sin_addr), ntohs(device->defaddr.sin_port)); 00524 ast_cli(fd, " Def. Username: %s\n", device->defaultuser); 00525 ast_cli(fd, " Codecs : "); 00526 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, device->capability); 00527 ast_cli(fd, "%s\n", codec_buf); 00528 ast_cli(fd, " Codec Order : ("); 00529 print_codec_to_cli(fd, &device->prefs); 00530 ast_cli(fd, ")\n"); 00531 00532 ast_cli(fd, " LastMsgsSent : %d\n", device->mailbox.lastmsgssent); 00533 ast_cli(fd, " SIP Options : "); 00534 if (device->sipoptions) { 00535 sip_options_print(device->sipoptions, fd); 00536 } else 00537 ast_cli(fd, "(none)"); 00538 ast_cli(fd, "\n"); 00539 00540 device_status(device, status, sizeof(status)); 00541 ast_cli(fd, " Status : %s\n", status); 00542 ast_cli(fd, " Useragent : %s\n", device->useragent); 00543 ast_cli(fd, " Reg. Contact : %s\n", device->fullcontact); 00544 if (device->chanvars) { 00545 ast_cli(fd, " Variables :\n"); 00546 for (v = device->chanvars ; v ; v = v->next) 00547 ast_cli(fd, " %s = %s\n", v->name, v->value); 00548 } 00549 ast_cli(fd,"\n"); 00550 device_unref(device); 00551 } else if (device && type == 1) { /* manager listing */ 00552 char buf[256]; 00553 astman_append(s, "Channeltype: SIP\r\n"); 00554 astman_append(s, "ObjectName: %s\r\n", device->name); 00555 astman_append(s, "SIPDomain: %s\r\n", device->domain); 00556 astman_append(s, "ChanObjectType: device\r\n"); 00557 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(device->secret)?"N":"Y"); 00558 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(device->md5secret)?"N":"Y"); 00559 astman_append(s, "Context: %s\r\n", device->extra.context); 00560 astman_append(s, "Language: %s\r\n", device->language); 00561 if (!ast_strlen_zero(device->extra.accountcode)) 00562 astman_append(s, "Accountcode: %s\r\n", device->extra.accountcode); 00563 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(device->extra.amaflags)); 00564 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(device->callingpres)); 00565 if (!ast_strlen_zero(device->extra.fromuser)) 00566 astman_append(s, "SIP-FromUser: %s\r\n", device->extra.fromuser); 00567 if (!ast_strlen_zero(device->extra.fromdomain)) 00568 astman_append(s, "SIP-FromDomain: %s\r\n", device->extra.fromdomain); 00569 astman_append(s, "Callgroup: "); 00570 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), device->callgroup)); 00571 astman_append(s, "Pickupgroup: "); 00572 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), device->pickupgroup)); 00573 astman_append(s, "VoiceMailbox: %s\r\n", device->mailbox.mailbox); 00574 astman_append(s, "TransferMode: %s\r\n", transfermode2str(device->allowtransfer)); 00575 astman_append(s, "LastMsgsSent: %d\r\n", device->mailbox.lastmsgssent); 00576 astman_append(s, "Call limit: %d\r\n", device->call_limit); 00577 astman_append(s, "MaxCallBR: %d kbps\r\n", device->maxcallbitrate); 00578 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&device->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 00579 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), device->extra.cid_name, device->extra.cid_num, "")); 00580 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,device->expire)); 00581 astman_append(s, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(&device->flags[0], SIP_INSECURE_PORT), ast_test_flag(&device->flags[0], SIP_INSECURE_INVITE))); 00582 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&device->flags[0], SIP_NAT))); 00583 astman_append(s, "ACL: %s\r\n", (device->ha?"Y":"N")); 00584 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&device->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 00585 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&device->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 00586 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&device->flags[0], SIP_USEREQPHONE)?"Y":"N")); 00587 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&device->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 00588 astman_append(s, "T38pt-UDPTL: %s\n", ast_test_flag(&device->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Y":"N"); 00589 astman_append(s, "T38pt-RTP: %s\n", ast_test_flag(&device->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Y":"N"); 00590 astman_append(s, "T38pt-TCP: %s\n", ast_test_flag(&device->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Y":"N"); 00591 00592 /* - is enumerated */ 00593 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&device->flags[0], SIP_DTMF))); 00594 astman_append(s, "ToHost: %s\r\n", device->extra.tohost); 00595 astman_append(s, "Address-IP: %s\r\nAddress-Port: %d\r\n", device->addr.sin_addr.s_addr ? ast_inet_ntoa(device->addr.sin_addr) : "", ntohs(device->addr.sin_port)); 00596 astman_append(s, "Default-addr-IP: %s\r\nDefault-addr-port: %d\r\n", ast_inet_ntoa(device->defaddr.sin_addr), ntohs(device->defaddr.sin_port)); 00597 astman_append(s, "Default-Username: %s\r\n", device->defaultuser); 00598 if (!ast_strlen_zero(global.regcontext)) 00599 astman_append(s, "RegExtension: %s\r\n", device->extra.regexten); 00600 astman_append(s, "Codecs: "); 00601 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, device->capability); 00602 astman_append(s, "%s\r\n", codec_buf); 00603 astman_append(s, "CodecOrder: "); 00604 pref = &device->prefs; 00605 for(x = 0; x < 32 ; x++) { 00606 codec = ast_codec_pref_index(pref,x); 00607 if (!codec) 00608 break; 00609 astman_append(s, "%s", ast_getformatname(codec)); 00610 if (x < 31 && ast_codec_pref_index(pref,x+1)) 00611 astman_append(s, ","); 00612 } 00613 00614 astman_append(s, "\r\n"); 00615 astman_append(s, "Status: "); 00616 device_status(device, status, sizeof(status)); 00617 astman_append(s, "%s\r\n", status); 00618 astman_append(s, "SIP-Useragent: %s\r\n", device->useragent); 00619 astman_append(s, "Reg-Contact : %s\r\n", device->fullcontact); 00620 if (device->chanvars) { 00621 for (v = device->chanvars ; v ; v = v->next) { 00622 astman_append(s, "ChanVariable:\n"); 00623 astman_append(s, " %s,%s\r\n", v->name, v->value); 00624 } 00625 } 00626 00627 device_unref(device); 00628 00629 } else { 00630 ast_cli(fd,"Device %s not found.\n", argv[3]); 00631 ast_cli(fd,"\n"); 00632 } 00633 00634 return RESULT_SUCCESS; 00635 } 00636 00637 /*! \brief Show one peer in detail */ 00638 static int sip_show_device(int fd, int argc, const char *argv[]) 00639 { 00640 return _sip_show_device(0, fd, NULL, NULL, argc, argv); 00641 } 00642 00643 /*! \brief Show SIP peers in the manager API */ 00644 int manager_sip_show_device( struct mansession *s, const struct message *m) 00645 { 00646 const char *id = astman_get_header(m,"ActionID"); 00647 const char *a[4]; 00648 const char *peer; 00649 int ret; 00650 00651 peer = astman_get_header(m,"Peer"); 00652 if (ast_strlen_zero(peer)) { 00653 astman_send_error(s, m, "Peer: <name> missing.\n"); 00654 return 0; 00655 } 00656 a[0] = "sip3"; 00657 a[1] = "show"; 00658 a[2] = "peer"; 00659 a[3] = peer; 00660 00661 if (!ast_strlen_zero(id)) 00662 astman_append(s, "ActionID: %s\r\n",id); 00663 ret = _sip_show_device(1, -1, s, m, 4, a ); 00664 astman_append(s, "\r\n\r\n" ); 00665 return ret; 00666 } 00667 00668 00669 00670 /*! \brief Show SIP Registry (registrations with other SIP proxies */ 00671 static int sip_show_registry(int fd, int argc, char *argv[]) 00672 { 00673 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 00674 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 00675 char host[80]; 00676 char tmpdat[256]; 00677 struct tm tm; 00678 00679 00680 if (argc != 3) 00681 return RESULT_SHOWUSAGE; 00682 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 00683 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 00684 ASTOBJ_RDLOCK(iterator); 00685 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 00686 if (iterator->regtime) { 00687 ast_localtime(&iterator->regtime, &tm, NULL); 00688 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 00689 } else { 00690 tmpdat[0] = 0; 00691 } 00692 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 00693 ASTOBJ_UNLOCK(iterator); 00694 } while(0)); 00695 return RESULT_SUCCESS; 00696 #undef FORMAT 00697 #undef FORMAT2 00698 } 00699 00700 /*! \brief List global settings for the SIP channel */ 00701 static int sip_show_settings(int fd, int argc, char *argv[]) 00702 { 00703 int realtimepeers; 00704 int realtimeusers; 00705 00706 realtimepeers = ast_check_realtime("sip3peers"); 00707 realtimeusers = ast_check_realtime("sip3users"); 00708 00709 if (argc != 3) 00710 return RESULT_SHOWUSAGE; 00711 ast_cli(fd, "\n\nGlobal Settings:\n"); 00712 ast_cli(fd, "----------------\n"); 00713 ast_cli(fd, " SIP Port: %d\n", ntohs(sipnet.bindaddr.sin_port)); 00714 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(sipnet.bindaddr.sin_addr)); 00715 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global.flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 00716 ast_cli(fd, " AutoCreatePeer: %s\n", global.autocreatepeer ? "Yes" : "No"); 00717 ast_cli(fd, " Allow unknown access: %s\n", global.allowguest ? "Yes" : "No"); 00718 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global.flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 00719 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global.flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 00720 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global.flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 00721 ast_cli(fd, " SIP domain support: %s\n", domains_configured() ? "No" : "Yes"); 00722 ast_cli(fd, " Call to non-local dom.: %s\n", global.allow_external_domains ? "Yes" : "No"); 00723 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global.flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 00724 ast_cli(fd, " Our auth realm %s\n", global.realm); 00725 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 00726 ast_cli(fd, " Always auth rejects: %s\n", global.alwaysauthreject ? "Yes" : "No"); 00727 ast_cli(fd, " User Agent: %s\n", global.useragent); 00728 ast_cli(fd, " MWI checking interval: %d secs\n", global.mwitime); 00729 ast_cli(fd, " Reg. context: %s\n", S_OR(global.regcontext, "(not set)")); 00730 ast_cli(fd, " Caller ID: %s\n", global.default_callerid); 00731 ast_cli(fd, " From: Domain: %s\n", global.default_fromdomain); 00732 ast_cli(fd, " Record SIP history: %s\n", global.recordhistory ? "On" : "Off"); 00733 ast_cli(fd, " Call Events: %s\n", global.callevents ? "On" : "Off"); 00734 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global.tos_sip)); 00735 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global.tos_audio)); 00736 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global.tos_video)); 00737 ast_cli(fd, " IP ToS SIP presence: %s\n", ast_tos2str(global.tos_presense)); 00738 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global.flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 00739 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global.flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 00740 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global.flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 00741 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global.flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 00742 ast_cli(fd, " Jitterbuffer enabled: %s\n", ast_test_flag(&global.jbconf, AST_JB_ENABLED) ? "Yes" : "No"); 00743 ast_cli(fd, " Jitterbuffer forced: %s\n", ast_test_flag(&global.jbconf, AST_JB_FORCED) ? "Yes" : "No"); 00744 ast_cli(fd, " Jitterbuffer max size: %ld\n", global.jbconf.max_size); 00745 ast_cli(fd, " Jitterbuffer resync: %ld\n", global.jbconf.resync_threshold); 00746 ast_cli(fd, " Jitterbuffer impl: %s\n", global.jbconf.impl); 00747 ast_cli(fd, " Jitterbuffer log: %s\n", ast_test_flag(&global.jbconf, AST_JB_LOG) ? "Yes" : "No"); 00748 ast_cli(fd, " SIP debug level: %s\n", global.debuglevel == SIPDEBUG_ALL ? "Everything" : (global.debuglevel == SIPDEBUG_CALLS ? "Calls" : "No OPTION messages")); 00749 if (!realtimepeers && !realtimeusers) 00750 ast_cli(fd, " SIP realtime: Disabled\n" ); 00751 else 00752 ast_cli(fd, " SIP realtime: Enabled\n" ); 00753 00754 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 00755 ast_cli(fd, "---------------------------\n"); 00756 ast_cli(fd, " Codecs: "); 00757 print_codec_to_cli(fd, &global.default_prefs); 00758 ast_cli(fd, "\n"); 00759 ast_cli(fd, " Relax DTMF: %s\n", global.relaxdtmf ? "Yes" : "No"); 00760 ast_cli(fd, " Compact SIP headers: %s\n", global.compactheaders ? "Yes" : "No"); 00761 ast_cli(fd, " RTP Keepalive: %d %s\n", global.rtptimer.rtpkeepalive, global.rtptimer.rtpkeepalive ? "" : "(Disabled)" ); 00762 ast_cli(fd, " RTP Timeout: %d %s\n", global.rtptimer.rtptimeout, global.rtptimer.rtptimeout ? "" : "(Disabled)" ); 00763 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global.rtptimer.rtpholdtimeout, global.rtptimer.rtpholdtimeout ? "" : "(Disabled)"); 00764 ast_cli(fd, " MWI NOTIFY mime type: %s\n", global.default_notifymime); 00765 ast_cli(fd, " DNS SRV lookup: %s\n", global.srvlookup ? "Yes" : "No"); 00766 ast_cli(fd, " Reg. min duration %d secs\n", expiry.min_expiry); 00767 ast_cli(fd, " Reg. max duration: %d secs\n", expiry.max_expiry); 00768 ast_cli(fd, " Reg. default duration: %d secs\n", expiry.default_expiry); 00769 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global.reg_timeout); 00770 ast_cli(fd, " Outbound reg. attempts: %d\n", global.regattempts_max); 00771 ast_cli(fd, " Notify ringing state: %s\n", global.notifyringing ? "Yes" : "No"); 00772 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global.allowtransfer)); 00773 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", global.default_maxcallbitrate); 00774 ast_cli(fd, "\nTimer Settings:\n"); 00775 ast_cli(fd, "-----------------\n"); 00776 ast_cli(fd, " SIP Timer T1 minimum: %d\n", global.t1min); 00777 ast_cli(fd, " SIP Timer T1 default: %d\n", global.t1default); 00778 ast_cli(fd, " SIP Timer T2: %d\n", global.t2default); 00779 ast_cli(fd, " SIP Timer T4: %d\n", global.t4default); 00780 ast_cli(fd, " SIP Timer B: %d\n", global.siptimer_b); 00781 ast_cli(fd, " SIP Timer F: %d\n", global.siptimer_f); 00782 ast_cli(fd, "\nDefault Settings:\n"); 00783 ast_cli(fd, "-----------------\n"); 00784 ast_cli(fd, " Context: %s\n", global.default_context); 00785 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global.flags[0], SIP_NAT))); 00786 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global.flags[0], SIP_DTMF))); 00787 ast_cli(fd, " Qualify: %d\n", global.default_qualify); 00788 ast_cli(fd, " Qualify timer OK: %d sec\n", global.default_qualifycheck_ok); 00789 ast_cli(fd, " Qualify timer not OK: %d sec\n", global.default_qualifycheck_notok); 00790 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global.flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 00791 ast_cli(fd, " Progress inband: %s\n", (ast_test_flag(&global.flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER) ? "Never" : (ast_test_flag(&global.flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NO) ? "No" : "Yes" ); 00792 ast_cli(fd, " Language: %s\n", S_OR(global.default_language, "(Defaults to English)")); 00793 ast_cli(fd, " MOH Interpret: %s\n", global.default_mohinterpret); 00794 ast_cli(fd, " MOH Suggest: %s\n", global.default_mohsuggest); 00795 ast_cli(fd, " Voice Mail Extension: %s\n", global.default_vmexten); 00796 00797 00798 if (realtimepeers || realtimeusers) { 00799 ast_cli(fd, "\nRealtime SIP Settings:\n"); 00800 ast_cli(fd, "----------------------\n"); 00801 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 00802 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 00803 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global.flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 00804 ast_cli(fd, " Update: %s\n", ast_test_flag(&global.flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 00805 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global.flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 00806 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global.flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 00807 ast_cli(fd, " Auto Clear: %d\n", global.rtautoclear); 00808 } 00809 ast_cli(fd, "\n----\n"); 00810 return RESULT_SUCCESS; 00811 } 00812 00813 /*! \brief Show details of one active dialog */ 00814 static int sip_show_channel(int fd, int argc, char *argv[]) 00815 { 00816 struct sip_dialog *cur; 00817 size_t len; 00818 int found = 0; 00819 00820 if (argc != 4) 00821 return RESULT_SHOWUSAGE; 00822 len = strlen(argv[3]); 00823 dialoglist_lock(); 00824 for (cur = dialoglist; cur; cur = cur->next) { 00825 if (!strncasecmp(cur->callid, argv[3], len)) { 00826 char formatbuf[BUFSIZ/2]; 00827 ast_cli(fd,"\n"); 00828 if (cur->subscribed != NONE) 00829 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 00830 else 00831 ast_cli(fd, " * SIP Call\n"); 00832 ast_cli(fd, " State: %s\n", dialogstate2str(cur->state)); 00833 ast_cli(fd, " Direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING)?"Outgoing":"Incoming"); 00834 ast_cli(fd, " Call-ID: %s\n", cur->callid); 00835 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 00836 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 00837 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 00838 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 00839 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 00840 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 00841 ast_cli(fd, " T.38 support %s\n", cur->udptl ? "Yes" : "No"); 00842 ast_cli(fd, " Video support %s\n", cur->vrtp ? "Yes" : "No"); 00843 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 00844 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 00845 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 00846 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 00847 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 00848 ast_cli(fd, " Audio IP: %s %s\n", ast_inet_ntoa(cur->redirip.sin_addr.s_addr ? cur->redirip.sin_addr : cur->ourip), cur->redirip.sin_addr.s_addr ? "(Outside bridge)" : "(local)" ); 00849 ast_cli(fd, " Our Tag: %s\n", cur->tag); 00850 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 00851 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 00852 if (!ast_strlen_zero(cur->username)) 00853 ast_cli(fd, " Username: %s\n", cur->username); 00854 if (!ast_strlen_zero(cur->peername)) 00855 ast_cli(fd, " Peername: %s\n", cur->peername); 00856 if (!ast_strlen_zero(cur->uri)) 00857 ast_cli(fd, " Original uri: %s\n", cur->uri); 00858 if (!ast_strlen_zero(cur->cid_num)) 00859 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 00860 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 00861 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 00862 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 00863 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 00864 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 00865 ast_cli(fd, " SIP Options: "); 00866 if (cur->sipoptions) { 00867 sip_options_print(cur->sipoptions, fd); 00868 } else 00869 ast_cli(fd, "(none)\n"); 00870 ast_cli(fd, "\n\n"); 00871 found++; 00872 } 00873 } 00874 dialoglist_unlock(); 00875 if (!found) 00876 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 00877 return RESULT_SUCCESS; 00878 } 00879 00880 /*! \brief Show history details of one dialog */ 00881 static int sip_show_history(int fd, int argc, char *argv[]) 00882 { 00883 struct sip_dialog *cur; 00884 size_t len; 00885 int found = 0; 00886 00887 if (argc != 4) 00888 return RESULT_SHOWUSAGE; 00889 if (!global.recordhistory) 00890 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 00891 len = strlen(argv[3]); 00892 dialoglist_lock(); 00893 for (cur = dialoglist; cur; cur = cur->next) { 00894 if (!strncasecmp(cur->callid, argv[3], len)) { 00895 struct sip_history *hist; 00896 int x = 0; 00897 00898 ast_cli(fd,"\n"); 00899 if (cur->subscribed != NONE) 00900 ast_cli(fd, " * Subscription\n"); 00901 else 00902 ast_cli(fd, " * SIP Call\n"); 00903 if (cur->history) { 00904 AST_LIST_TRAVERSE(cur->history, hist, list) 00905 ast_cli(fd, "%d. %s\n", ++x, hist->event); 00906 } 00907 if (x == 0) 00908 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 00909 found++; 00910 } 00911 } 00912 dialoglist_unlock(); 00913 if (!found) 00914 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 00915 return RESULT_SUCCESS; 00916 } 00917 00918 /*! \brief Do completion on peer name */ 00919 GNURK char *complete_sip_device(const char *word, int state, int flags2) 00920 { 00921 char *result = NULL; 00922 int wordlen = strlen(word); 00923 int which = 0; 00924 00925 ASTOBJ_CONTAINER_TRAVERSE(&devicelist, !result, do { 00926 /* locking of the object is not required because only the name and flags are being compared */ 00927 if (!strncasecmp(word, iterator->name, wordlen) && 00928 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 00929 ++which > state) 00930 result = ast_strdup(iterator->name); 00931 } while(0) ); 00932 return result; 00933 } 00934 00935 /*! \brief Support routine for 'sip show peer' CLI */ 00936 GNURK char *complete_sip_show_device(const char *line, const char *word, int pos, int state) 00937 { 00938 if (pos == 3) 00939 return complete_sip_device(word, state, 0); 00940 00941 return NULL; 00942 } 00943 00944 /*! \brief Support routine for 'sip show channel' CLI */ 00945 static char *complete_sipch(const char *line, const char *word, int pos, int state) 00946 { 00947 int which=0; 00948 struct sip_dialog *cur; 00949 char *c = NULL; 00950 int wordlen = strlen(word); 00951 00952 dialoglist_lock(); 00953 for (cur = dialoglist; cur; cur = cur->next) { 00954 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 00955 c = ast_strdup(cur->callid); 00956 break; 00957 } 00958 } 00959 dialoglist_unlock(); 00960 return c; 00961 } 00962 00963 00964 /*! \brief Support routine for 'sip debug peer' CLI */ 00965 static char *complete_sip_debug_device(const char *line, const char *word, int pos, int state) 00966 { 00967 if (pos == 3) 00968 return complete_sip_device(word, state, 0); 00969 00970 return NULL; 00971 } 00972 00973 00974 /*! \brief SIP show channels CLI (main function) */ 00975 static int __sip_show_channels(int fd, int argc, char *argv[], int subscriptions) 00976 { 00977 #define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" 00978 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-4.4s %-7.7s %-15.15s\n" 00979 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s %-10.10s\n" 00980 struct sip_dialog *cur; 00981 int numchans = 0; 00982 const char *referstatus = NULL; 00983 00984 if (argc != 3) 00985 return RESULT_SHOWUSAGE; 00986 dialoglist_lock(); 00987 cur = dialoglist; 00988 if (!subscriptions) 00989 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 00990 else 00991 ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox"); 00992 for (; cur; cur = cur->next) { 00993 dialoglist_unlock(); 00994 referstatus = ""; 00995 if (cur->refer) { /* SIP transfer in progress */ 00996 referstatus = referstatus2str(cur->refer->status); 00997 } 00998 if (cur->subscribed == NONE && !subscriptions) { 00999 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 01000 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 01001 cur->callid, 01002 cur->ocseq, cur->icseq, 01003 ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), 01004 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 01005 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 01006 cur->lastmsg , 01007 referstatus 01008 ); 01009 numchans++; 01010 } 01011 if (cur->subscribed != NONE && subscriptions) { 01012 ast_cli(fd, FORMAT3, ast_inet_ntoa(cur->sa.sin_addr), 01013 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 01014 cur->callid, 01015 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 01016 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 01017 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 01018 subscription_type2str(cur->subscribed), 01019 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox.mailbox : "<none>") : "<none>" 01020 ); 01021 numchans++; 01022 } 01023 dialoglist_lock(); 01024 } 01025 dialoglist_unlock(); 01026 if (!subscriptions) 01027 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 01028 else 01029 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 01030 return RESULT_SUCCESS; 01031 #undef FORMAT 01032 #undef FORMAT2 01033 #undef FORMAT3 01034 } 01035 01036 /*! \brief Show active SIP channels */ 01037 static int sip_show_channels(int fd, int argc, char *argv[]) 01038 { 01039 return __sip_show_channels(fd, argc, argv, 0); 01040 } 01041 01042 /*! \brief Show active SIP subscriptions */ 01043 static int sip_show_subscriptions(int fd, int argc, char *argv[]) 01044 { 01045 return __sip_show_channels(fd, argc, argv, 1); 01046 } 01047 01048 01049 /*! \brief Start reload process from CLI */ 01050 static int cli_sip_reload(int fd, int argc, char *argv[]) 01051 { 01052 return sip_reload(fd); 01053 01054 } 01055 01056 /*! \brief List configuration options */ 01057 static int cli_sip_listconfigs(int fd, int argc, char *argv[]) 01058 { 01059 return sip_listconfigs(fd); 01060 } 01061 01062 01063 /*! \brief Enable SIP Debugging in CLI */ 01064 static int sip_do_debug_ip(int fd, int argc, char *argv[]) 01065 { 01066 struct hostent *hp; 01067 struct ast_hostent ahp; 01068 int port = 0; 01069 char *p, *arg; 01070 01071 if (argc != 4) 01072 return RESULT_SHOWUSAGE; 01073 p = arg = argv[3]; 01074 strsep(&p, ":"); 01075 if (p) 01076 port = atoi(p); 01077 hp = ast_gethostbyname(arg, &ahp); 01078 if (hp == NULL) 01079 return RESULT_SHOWUSAGE; 01080 01081 sipnet.debugaddr.sin_family = AF_INET; 01082 memcpy(&sipnet.debugaddr.sin_addr, hp->h_addr, sizeof(sipnet.debugaddr.sin_addr)); 01083 sipnet.debugaddr.sin_port = htons(port); 01084 if (port == 0) 01085 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(sipnet.debugaddr.sin_addr)); 01086 else 01087 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(sipnet.debugaddr.sin_addr), port); 01088 01089 ast_set_flag(&global.flags[1], SIP_PAGE2_DEBUG_CONSOLE); 01090 01091 return RESULT_SUCCESS; 01092 } 01093 01094 01095 /*! \brief sip_do_debug_device: Turn on SIP debugging with peer mask */ 01096 static int sip_do_debug_device(int fd, int argc, char *argv[]) 01097 { 01098 struct sip_device *peer; 01099 if (argc != 4) 01100 return RESULT_SHOWUSAGE; 01101 peer = find_device(argv[3], NULL, 1); 01102 if (peer) { 01103 if (peer->addr.sin_addr.s_addr) { 01104 sipnet.debugaddr.sin_family = AF_INET; 01105 sipnet.debugaddr.sin_addr = peer->addr.sin_addr; 01106 sipnet.debugaddr.sin_port = peer->addr.sin_port; 01107 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(sipnet.debugaddr.sin_addr), ntohs(sipnet.debugaddr.sin_port)); 01108 ast_set_flag(&global.flags[1], SIP_PAGE2_DEBUG_CONSOLE); 01109 } else 01110 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[3]); 01111 device_unref(peer); 01112 } else 01113 ast_cli(fd, "No such peer '%s'\n", argv[3]); 01114 return RESULT_SUCCESS; 01115 } 01116 01117 /*! \brief Turn on SIP debugging (CLI command) */ 01118 static int sip_do_debug(int fd, int argc, char *argv[]) 01119 { 01120 int oldsipdebug = sipdebug_console; 01121 if (argc != 3) { 01122 if (argc != 4) 01123 return RESULT_SHOWUSAGE; 01124 else if (strcmp(argv[2], "ip") == 0) 01125 return sip_do_debug_ip(fd, argc, argv); 01126 else if (strcmp(argv[2], "peer") == 0) 01127 return sip_do_debug_device(fd, argc, argv); 01128 else 01129 return RESULT_SHOWUSAGE; 01130 } 01131 ast_set_flag(&global.flags[1], SIP_PAGE2_DEBUG_CONSOLE); 01132 memset(&sipnet.debugaddr, 0, sizeof(sipnet.debugaddr)); 01133 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 01134 return RESULT_SUCCESS; 01135 } 01136 01137 /*! \brief Disable SIP Debugging in CLI */ 01138 static int sip_no_debug(int fd, int argc, char *argv[]) 01139 { 01140 if (argc != 3) 01141 return RESULT_SHOWUSAGE; 01142 ast_clear_flag(&global.flags[1], SIP_PAGE2_DEBUG_CONSOLE); 01143 ast_cli(fd, "SIP Debugging Disabled\n"); 01144 return RESULT_SUCCESS; 01145 } 01146 01147 01148 /*! \brief Enable SIP History logging (CLI) */ 01149 static int sip_do_history(int fd, int argc, char *argv[]) 01150 { 01151 if (argc != 3) { 01152 return RESULT_SHOWUSAGE; 01153 } 01154 global.recordhistory = TRUE; 01155 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 01156 return RESULT_SUCCESS; 01157 } 01158 01159 /*! \brief Disable SIP History logging (CLI) */ 01160 static int sip_no_history(int fd, int argc, char *argv[]) 01161 { 01162 if (argc != 3) { 01163 return RESULT_SHOWUSAGE; 01164 } 01165 global.recordhistory = FALSE; 01166 ast_cli(fd, "SIP History Recording Disabled\n"); 01167 return RESULT_SUCCESS; 01168 } 01169 01170 01171 /*! \brief Support routine for 'sip notify' CLI */ 01172 static char *complete_sipnotify(const char *line, const char *word, int pos, int state) 01173 { 01174 char *c = NULL; 01175 01176 if (pos == 2) { 01177 int which = 0; 01178 char *cat = NULL; 01179 int wordlen = strlen(word); 01180 01181 /* do completion for notify type */ 01182 01183 if (!notify_types) 01184 return NULL; 01185 01186 while ( (cat = ast_category_browse(notify_types, cat)) ) { 01187 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 01188 c = ast_strdup(cat); 01189 break; 01190 } 01191 } 01192 return c; 01193 } 01194 01195 if (pos > 2) 01196 return complete_sip_device(word, state, 0); 01197 01198 return NULL; 01199 } 01200 01201 /*! \brief Support routine for 'sip prune realtime peer' CLI */ 01202 static char *complete_sip_prune_realtime_peer(const char *line, const char *word, int pos, int state) 01203 { 01204 if (pos == 4) 01205 return complete_sip_device(word, state, SIP_PAGE2_RTCACHEFRIENDS); 01206 return NULL; 01207 } 01208 01209 static char show_domains_usage[] = 01210 "Usage: sip list domains\n" 01211 " Lists all configured SIP local domains.\n" 01212 " Asterisk only responds to SIP messages to local domains.\n"; 01213 01214 static char notify_usage[] = 01215 "Usage: sip notify <type> <peer> [<peer>...]\n" 01216 " Send a NOTIFY message to a SIP peer or peers\n" 01217 " Message types are defined in sip_notify.conf\n"; 01218 01219 static char show_inuse_usage[] = 01220 "Usage: sip list inuse [all]\n" 01221 " List all SIP users and peers usage counters and limits.\n" 01222 " Add option \"all\" to show all devices, not only those with a limit.\n"; 01223 01224 static char show_channels_usage[] = 01225 "Usage: sip list channels\n" 01226 " Lists all currently active SIP channels.\n"; 01227 01228 static char show_channel_usage[] = 01229 "Usage: sip show channel <channel>\n" 01230 " Provides detailed status on a given SIP channel.\n"; 01231 01232 static char show_history_usage[] = 01233 "Usage: sip show history <channel>\n" 01234 " Provides detailed dialog history on a given SIP channel.\n"; 01235 01236 static char show_devices_usage[] = 01237 "Usage: sip list devices [like <pattern>]\n" 01238 " Lists all known SIP devices.\n" 01239 " Optional regular expression pattern is used to filter the devices list.\n"; 01240 01241 static char show_device_usage[] = 01242 "Usage: sip show device <name> [load]\n" 01243 " Shows all details on one SIP device and the current status.\n" 01244 " Option \"load\" forces lookup of peer in realtime storage.\n"; 01245 01246 static char prune_realtime_usage[] = 01247 "Usage: sip prune realtime peer [<name>|all|like <pattern>]\n" 01248 " Prunes object(s) from the cache.\n" 01249 " Optional regular expression pattern is used to filter the objects.\n"; 01250 01251 static char show_reg_usage[] = 01252 "Usage: sip list registry\n" 01253 " Lists all service registration requests and status.\n"; 01254 01255 static char debug_usage[] = 01256 "Usage: sip debug on/off\n" 01257 " Enables dumping of SIP packets for debugging purposes\n\n" 01258 " sip debug ip <host[:PORT]>\n" 01259 " Enables dumping of SIP packets to and from host.\n\n" 01260 " sip debug peer <peername>\n" 01261 " Enables dumping of SIP packets to and from host.\n" 01262 " Require peer to be registered.\n"; 01263 01264 static char no_debug_usage[] = 01265 "Usage: sip debug off\n" 01266 " Disables dumping of SIP packets for debugging purposes\n"; 01267 01268 static char no_history_usage[] = 01269 "Usage: sip history off\n" 01270 " Disables recording of SIP dialog history for debugging purposes\n"; 01271 01272 static char history_usage[] = 01273 "Usage: sip history on\n" 01274 " Enables recording of SIP dialog history for debugging purposes.\n" 01275 "Use 'sip show history' to view the history of a call number.\n"; 01276 01277 static char sip_reload_usage[] = 01278 "Usage: sip reload\n" 01279 " Reloads SIP configuration from sip.conf\n"; 01280 01281 static char show_subscriptions_usage[] = 01282 "Usage: sip list subscriptions\n" 01283 " Lists active SIP subscriptions for extension states\n"; 01284 01285 static char show_objects_usage[] = 01286 "Usage: sip list objects\n" 01287 " Lists status of known SIP objects\n"; 01288 01289 static char show_settings_usage[] = 01290 "Usage: sip list settings\n" 01291 " Provides detailed list of the configuration of the SIP channel.\n"; 01292 01293 static char sip_listconfig_usage[] = 01294 "Usage: sip list configs\n" 01295 " Provides detailed list of the configuration options of the SIP channel.\n"; 01296 01297 01298 static struct ast_cli_entry cli_sip[] = { 01299 { { "sip", "show", "channels", NULL }, 01300 sip_show_channels, "List active SIP channels", 01301 show_channels_usage }, 01302 01303 { { "sip", "show", "domains", NULL }, 01304 sip_show_domains, "List our local SIP domains.", 01305 show_domains_usage }, 01306 01307 { { "sip", "show", "inuse", NULL }, 01308 sip_show_inuse, "List all call limits and their current usage level", 01309 show_inuse_usage }, 01310 01311 { { "sip", "show", "objects", NULL }, 01312 sip_show_objects, "List all SIP object allocations", 01313 show_objects_usage }, 01314 01315 { { "sip", "show", "devices", NULL }, 01316 sip_show_devices, "List defined SIP devices (phones, trunks, services)", 01317 show_devices_usage }, 01318 01319 { { "sip", "list", "registry", NULL }, 01320 sip_show_registry, "List SIP registration status for services", 01321 show_reg_usage }, 01322 01323 { { "sip", "show", "settings", NULL }, 01324 sip_show_settings, "Show SIP global settings", 01325 show_settings_usage }, 01326 01327 { { "sip", "show", "subscriptions", NULL }, 01328 sip_show_subscriptions, "List active SIP subscriptions", 01329 show_subscriptions_usage }, 01330 01331 { { "sip", "notify", NULL }, 01332 sip_notify, "Send a notify packet to a SIP device", 01333 notify_usage, complete_sipnotify }, 01334 01335 { { "sip", "show", "channel", NULL }, 01336 sip_show_channel, "Show detailed SIP channel info", 01337 show_channel_usage, complete_sipch }, 01338 01339 { { "sip", "show", "history", NULL }, 01340 sip_show_history, "Show SIP dialog history", 01341 show_history_usage, complete_sipch }, 01342 01343 { { "sip", "show", "device", NULL }, 01344 sip_show_device, "Show details on specific SIP device (phone, service, trunk)", 01345 show_device_usage, complete_sip_show_device }, 01346 01347 { { "sip", "prune", "realtime", NULL }, 01348 sip_prune_realtime, "Prune cached Realtime object(s)", 01349 prune_realtime_usage }, 01350 01351 { { "sip", "prune", "realtime", "peer", NULL }, 01352 sip_prune_realtime, "Prune cached Realtime peer(s)", 01353 prune_realtime_usage, complete_sip_prune_realtime_peer }, 01354 01355 { { "sip", "debug", "on", NULL }, 01356 sip_do_debug, "Enable SIP debugging", 01357 debug_usage }, 01358 01359 { { "sip", "debug", "ip", NULL }, 01360 sip_do_debug, "Enable SIP debugging on IP", 01361 debug_usage }, 01362 01363 { { "sip", "debug", "device", NULL }, 01364 sip_do_debug, "Enable SIP debugging on device-name", 01365 debug_usage, complete_sip_debug_device }, 01366 01367 { { "sip", "debug", "off", NULL }, 01368 sip_no_debug, "Disable SIP debugging", 01369 no_debug_usage }, 01370 01371 { { "sip", "history", "on", NULL }, 01372 sip_do_history, "Enable SIP history", 01373 history_usage }, 01374 01375 { { "sip", "history", "off", NULL }, 01376 sip_no_history, "Disable SIP history", 01377 no_history_usage }, 01378 01379 { { "sip", "reload", NULL }, 01380 cli_sip_reload, "Reload SIP configuration", 01381 sip_reload_usage }, 01382 01383 { { "sip", "list", "configs", NULL }, 01384 cli_sip_listconfigs, "List SIP coniguration options", 01385 sip_listconfig_usage }, 01386 }; 01387 01388 /*! \brief Register cli and manager commands */ 01389 void sip_cli_and_manager_commands_register() 01390 { 01391 /* Register CLI commands */ 01392 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 01393 /* Register manager commands */ 01394 ast_manager_register2("SIPdevices", EVENT_FLAG_SYSTEM, manager_sip_show_devices, 01395 "List SIP devices (text format)", mandescr_show_devices); 01396 ast_manager_register2("SIPshowdevice", EVENT_FLAG_SYSTEM, manager_sip_show_device, 01397 "Show SIP device (text format)", mandescr_show_device); 01398 } 01399 01400 /*! \brief Unregister cli and manager commands */ 01401 void sip_cli_and_manager_commands_unregister() 01402 { 01403 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 01404 ast_manager_unregister("SIPdevices"); 01405 ast_manager_unregister("SIPshowdevice"); 01406 } 01407