Index: channels/chan_sip.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v retrieving revision 1.473 diff -u -r1.473 chan_sip.c --- channels/chan_sip.c 18 Aug 2004 02:16:04 -0000 1.473 +++ channels/chan_sip.c 18 Aug 2004 17:18:42 -0000 @@ -5416,6 +5416,129 @@ } } + +#ifdef SIPGSNOTIFY +/* sip_gsnotify: Send reboot packet to grandstream phone. Requires knowledge + of file format to send to Grandstream. + + Content-Type: application/octet-stream + Event: sys-control + Content-Length: 24 + then it goes 24 bytes binary + + Syntax: + sip gsnotify [delete] +*/ +static int sip_gsnotify(int fd, int argc, char *argv[]) +{ + char *s; + char *peername; /* Peer to send information to */ + char *filename; /* File to read and send */ + int deletefileafternotify = 0; /* Whether or not to delete file */ + struct sip_request req; + struct sip_peer *peer; + struct sip_pvt *p; + char name[256] = ""; + char tmp[256]; + char tmp2[256] = ""; + char clen[20] = ""; + char iabuf[INET_ADDRSTRLEN]; + int rebootfile, len; + + + if (argc < 4) { + return RESULT_SHOWUSAGE; + } + + /* Get peer, filename, deleteoption */ + peername = argv[2]; + filename = argv[3]; + if (argc == 5) + if (strcasecmp(argv[4], "delete")) + deletefileafternotify = 1; + + /* Find peer */ + ast_mutex_lock(&peerl.lock); + peer = find_peer(peername, NULL); + + ast_mutex_unlock(&peerl.lock); + + if (!peer) { + ast_cli(fd, "GSNotify: Unable to find PEER %s\n", peername); + return -1; + } + + if ((rebootfile = open(filename, O_RDONLY)) < 0) { + ast_cli(fd, "GSNotify: Unable to open file %s\n", filename); + return -1; + } + + /* It's only 24 bytes, so we should be able to read it in one read */ + len = read(rebootfile, tmp, sizeof(tmp)); + if (len < 0) { + ast_cli (fd, "GSNotify: Read failed on file %s\n", filename); + close(rebootfile); + ast_mutex_unlock(&peerl.lock); + return -1; + + } + close(rebootfile); + if (deletefileafternotify) + unlink(filename); + + /* Allocate SIP packet */ + p = sip_alloc(NULL, NULL, 0); + if (!p) { + ast_log(LOG_WARNING, "Unable to build sip pvt data for GSNotify\n"); + return -1; + } + + /* Get peer name */ + strncpy(name, peer->name, sizeof(name) - 1); + + + /* Notify to full contact */ + ast_log(LOG_DEBUG, "GSNOTIFY: Checking if %s is available? \n", peer->name); + + if (create_addr(p, name) ){ + /* Maybe they're not registered, etc. */ + ast_cli(fd, "SIP GSNOTIFY: %s is not available. (Unreachable, not registred) \n", name); + 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 */ + if (p->nat != SIP_NAT_NEVER) + snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); + else /* Avoid RPORT */ + snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); + + build_callid(p->callid, sizeof(p->callid), p->ourip); + + /* Send NOTIFY */ + p->outgoing = 1; + + sip_scheddestroy(p, 15000); + + initreqprep(&req, p, "NOTIFY", NULL); + add_header(&req, "Event", "sys-control"); + add_header(&req, "Content-Type", "application/octet-stream"); + + snprintf(clen, sizeof(clen), "%d", (int)strlen(tmp)); + + /* READ FILE HERE */ + add_header(&req, "Content-Length", clen); + add_line(&req, tmp); + + return send_request(p, &req, 1, p->ocseq); + +} +#endif + /*--- sip_show_inuse: CLI Command to show calls within limits set by outgoinglimit and incominglimit ---*/ static int sip_show_inuse(int fd, int argc, char *argv[]) { @@ -6340,6 +6463,20 @@ { { "sip", "no", "history", NULL }, sip_no_history, "Disable SIP history", no_history_usage }; static struct ast_cli_entry cli_no_debug = { { "sip", "no", "debug", NULL }, sip_no_debug, "Disable SIP debugging", no_debug_usage }; +#ifdef SIPGSNOTIFY + +/* Forward declaration */ +static int sip_gsnotify(int fd, int argc, char *argv[]); + +static char sip_gsnotify_usage[] = +"Usage: sip gsnotify [delete]\n" +" Send special NOTIFY message to Grandstream phone to force reboot\n" +" (Requires knowledge on GS admin kit \n"; + +static struct ast_cli_entry cli_gsnotify = + { { "sip", "gsnotify", NULL }, sip_gsnotify, "Send reboot notify to grandstream IP Phone", sip_gsnotify_usage }; + +#endif static int sip_poke_peer_s(void *data) {