Index: channels/chan_sip.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v retrieving revision 1.170 diff -u -r1.170 chan_sip.c --- channels/chan_sip.c 25 Aug 2003 14:17:14 -0000 1.170 +++ channels/chan_sip.c 29 Aug 2003 21:06:23 -0000 @@ -2803,6 +2803,31 @@ return send_request(p, &req, 1, p->ocseq); } +static int transmit_reset(struct sip_pvt *p) +{ + struct sip_request req; + char tmp[256]; + char tmp2[256]; + char clen[20]; + initreqprep(&req, p, "NOTIFY", NULL); + add_header(&req, "Event", "check-sync"); + add_header(&req, "Content-Type", notifymime); + + snprintf(clen, sizeof(clen), "%d", strlen(tmp) + strlen(tmp2)); + add_header(&req, "Content-Length", clen); + add_line(&req, tmp); + add_line(&req, tmp2); + + if (!p->initreq.headers) { + /* Use this as the basis */ + copy_request(&p->initreq, &req); + parse(&p->initreq); + determine_firstline_parts(&p->initreq); + } + + return send_request(p, &req, 1, p->ocseq); +} + static int transmit_register(struct sip_registry *r, char *cmd, char *auth, char *authheader); static int sip_reregister(void *data) @@ -3975,6 +4000,66 @@ #undef FORMAT2 } +static int sip_send_reset_to_peer(struct sip_peer *peer) +{ + /* Derived from sip_send_mwi_to_peer */ + /* Called with peerl lock, but releases it */ + + struct sip_pvt *p; + char name[256] = ""; + + p = sip_alloc(NULL, NULL, 0); + if (!p) { + ast_log(LOG_WARNING, "Unable to build sip pvt data for RESET\n"); + ast_mutex_unlock(&peerl.lock); + return -1; + } + strncpy(name, peer->name, sizeof(name) - 1); + ast_mutex_unlock(&peerl.lock); + if (create_addr(p, name)) { + /* Maybe they're not registered, etc. */ + sip_destroy(p); + return 0; + } + /* Recalculate our side, and recalculate Call ID */ + if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) + memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); + /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ + snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", inet_ntoa(p->ourip), ourport, p->branch); + build_callid(p->callid, sizeof(p->callid), p->ourip); + + transmit_reset(p); + + sip_scheddestroy(p, 15000); + return 0; +} + +static int sip_reset_phone_peer(int fd, int argc, char *argv[]) +{ + struct sip_peer *peer; + if (argc != 4) + return RESULT_SHOWUSAGE; + ast_mutex_lock(&peerl.lock); + + /* Check incoming extension request. If it is 'all' then reset all SIP phones. + Otherwise, just reset the specified extension */ + + for (peer = peerl.peers;peer;peer = peer->next) { + if (!strcmp(argv[3],"all")) { + ast_log(LOG_DEBUG,"Sending Reset to %s\n",peer->username); + sip_send_reset_to_peer(peer); + } else { + if (!strcmp(peer->username,argv[3])) { + ast_log(LOG_DEBUG,"Sending Reset to %s\n",peer->username); + sip_send_reset_to_peer(peer); + } + } +} + ast_mutex_unlock(&peerl.lock); + return RESULT_SUCCESS; +} + + static char *regstate2str(int regstate) { switch(regstate) { @@ -4317,6 +4402,12 @@ "Usage: sip no debug\n" " Disables dumping of SIP packets for debugging purposes\n"; +static char show_reset_phone_peer[] = +"Usage: sip reset or \n" +" Resets the SIP phone at given extension\n" +" If \'all\' was specified, then all SIP phones will be rebooted\n\n" +"**Be sure you have updated your syncinfo.xml file!*.\n"; + static struct ast_cli_entry cli_show_users = { { "sip", "show", "users", NULL }, sip_show_users, "Show defined SIP users", show_users_usage }; static struct ast_cli_entry cli_show_channels = @@ -4333,7 +4424,8 @@ { { "sip", "debug", NULL }, sip_do_debug, "Enable SIP debugging", debug_usage }; static struct ast_cli_entry cli_no_debug = { { "sip", "no", "debug", NULL }, sip_no_debug, "Disable SIP debugging", no_debug_usage }; - +static struct ast_cli_entry cli_reset_phone = + { { "sip", "reset", "phone", NULL }, sip_reset_phone_peer, "Sending Reset Info", show_reset_phone_peer }; static int sip_poke_peer_s(void *data) { @@ -6003,6 +6095,7 @@ ast_cli_register(&cli_debug); ast_cli_register(&cli_no_debug); ast_cli_register(&cli_inuse_show); + ast_cli_register(&cli_reset_phone); sip_rtp.type = type; ast_rtp_proto_register(&sip_rtp); ast_mutex_lock(&peerl.lock);