![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
sip3_pokedevice.c File Reference
Olle E. Johansson <oej@edvina.net> (all the chan_sip3 changes)
Definition in file sip3_pokedevice.c.
#include "asterisk.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <regex.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/compiler.h"
#include "sip3.h"
#include "sip3funcs.h"
Include dependency graph for sip3_pokedevice.c:

Go to the source code of this file.
Functions | |
| void | handle_response_peerpoke (struct sip_dialog *p, int resp, struct sip_request *req) |
| Handle qualification responses (OPTIONS). | |
| void | sip_poke_all_peers (void) |
| Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions? | |
| int | sip_poke_noanswer (void *data) |
| React to lack of answer to Qualify poke. | |
| int | sip_poke_peer (struct sip_device *peer) |
| Check availability of peer, also keep NAT open. | |
| int | sip_poke_peer_s (void *data) |
| Poke peer (send qualify to check if peer is alive and well). | |
|
||||||||||||||||
|
Handle qualification responses (OPTIONS).
Definition at line 103 of file sip3_pokedevice.c. References ast_device_state_changed(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, sip_device::call, sip_globals::default_qualifycheck_notok, sip_globals::default_qualifycheck_ok, DIALOG_STATE_TERMINATED, dialogstatechange(), EVENT_FLAG_SYSTEM, sip_dialog::flags, global, sip_device::lastms, LOG_NOTICE, manager_event, sip_device::maxms, sip_device::pokeexpire, sip_device::ps, sip_dialog::relatedpeer, s, SIP_NEEDDESTROY, and sip_poke_peer_s(). 00104 { 00105 struct sip_device *peer = p->relatedpeer; 00106 int statechanged, is_reachable, was_reachable; 00107 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 00108 00109 if (!peer) 00110 return; 00111 00112 /* 00113 * Compute the response time to a ping (goes in peer->lastms.) 00114 * -1 means did not respond, 0 means unknown, 00115 * 1..maxms is a valid response, >maxms means late response. 00116 */ 00117 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 00118 pingtime = 1; 00119 00120 /* Now determine new state and whether it has changed. 00121 * Use some helper variables to simplify the writing 00122 * of the expressions. 00123 */ 00124 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 00125 is_reachable = pingtime <= peer->maxms; 00126 statechanged = peer->lastms == 0 /* yes, unknown before */ 00127 || was_reachable != is_reachable; 00128 00129 peer->lastms = pingtime; 00130 peer->call = NULL; 00131 if (statechanged) { 00132 const char *s = is_reachable ? "Reachable" : "Lagged"; 00133 00134 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 00135 peer->name, s, pingtime, peer->maxms); 00136 ast_device_state_changed("SIP/%s", peer->name); 00137 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 00138 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 00139 peer->name, s, pingtime); 00140 } 00141 00142 if (peer->pokeexpire > -1) 00143 ast_sched_del(sched, peer->pokeexpire); 00144 00145 /* Try again eventually */ 00146 peer->pokeexpire = ast_sched_add(sched, 00147 is_reachable ? global.default_qualifycheck_ok: global.default_qualifycheck_notok, 00148 sip_poke_peer_s, peer); 00149 00150 dialogstatechange(p, DIALOG_STATE_TERMINATED); 00151 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 00152 }
|
|
|
Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions?
Definition at line 239 of file sip3_pokedevice.c. References ast_sched_add(), ast_sched_del(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, devicelist, sip_poke_peer_s(), sipcounters, and channel_counters::static_peers. 00240 { 00241 int ms = 0; 00242 00243 if (!sipcounters.static_peers) /* No peers, just give up */ 00244 return; 00245 00246 ASTOBJ_CONTAINER_TRAVERSE(&devicelist, 1, do { 00247 ASTOBJ_WRLOCK(iterator); 00248 if (iterator->pokeexpire > -1) 00249 ast_sched_del(sched, iterator->pokeexpire); 00250 ms += 100; 00251 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, iterator); 00252 ASTOBJ_UNLOCK(iterator); 00253 } while (0) 00254 ); 00255 }
|
|
|
React to lack of answer to Qualify poke.
Definition at line 155 of file sip3_pokedevice.c. References ast_device_state_changed(), ast_log(), ast_sched_add(), sip_device::call, sip_globals::default_qualifycheck_notok, EVENT_FLAG_SYSTEM, global, sip_device::lastms, LOG_NOTICE, manager_event, sip_device::pokeexpire, sip_destroy(), and sip_poke_peer_s(). 00156 { 00157 struct sip_device *peer = data; 00158 00159 peer->pokeexpire = -1; 00160 if (peer->lastms > -1) { 00161 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 00162 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 00163 } 00164 if (peer->call) 00165 sip_destroy(peer->call); 00166 peer->call = NULL; 00167 peer->lastms = -1; 00168 ast_device_state_changed("SIP/%s", peer->name); 00169 /* Try again quickly */ 00170 peer->pokeexpire = ast_sched_add(sched, global.default_qualifycheck_notok, sip_poke_peer_s, peer); 00171 return 0; 00172 }
|
|
|
Check availability of peer, also keep NAT open.
Definition at line 177 of file sip3_pokedevice.c. References sip_network::__ourip, sip_device::addr, ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), build_callid_pvt(), build_via(), sip_device::call, DEFAULT_QUALIFY_MAXMS, sip_device::extra, FALSE, sip_dialog::flags, sip_device::flags, sip_device::lastms, LOG_NOTICE, sip_device::maxms, sip_dialog::ourip, sip_device::pokeexpire, sip_device::ps, sip_dialog::recv, sip_dialog::relatedpeer, sip_dialog::sa, sip_alloc(), sip_destroy(), SIP_FLAGS_TO_COPY, SIP_INVITE, SIP_OPTIONS, sip_ouraddrfor(), SIP_OUTGOING, SIP_PAGE2_FLAGS_TO_COPY, sip_poke_noanswer(), sipdebug, sipnet, sip_device_extra::tohost, and transmit_invite(). 00178 { 00179 struct sip_dialog *p; 00180 00181 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 00182 /* IF we have no IP, or this isn't to be monitored, return 00183 imeediately after clearing things out */ 00184 if (peer->pokeexpire > -1) 00185 ast_sched_del(sched, peer->pokeexpire); 00186 peer->lastms = 0; 00187 peer->pokeexpire = -1; 00188 peer->call = NULL; 00189 return 0; 00190 } 00191 if (peer->call > 0) { 00192 if (sipdebug) 00193 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 00194 sip_destroy(peer->call); 00195 } 00196 if (!(p = peer->call = sip_alloc(NULL, NULL, FALSE, SIP_OPTIONS))) 00197 return -1; 00198 00199 p->sa = peer->addr; 00200 p->recv = peer->addr; 00201 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 00202 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 00203 00204 /* Send OPTIONs to peer's fullcontact */ 00205 if (!ast_strlen_zero(peer->fullcontact)) 00206 ast_string_field_set(p, fullcontact, peer->fullcontact); 00207 00208 if (!ast_strlen_zero(peer->extra.tohost)) 00209 ast_string_field_set(p, tohost, peer->extra.tohost); 00210 else 00211 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 00212 00213 /* Recalculate our side, and recalculate Call ID */ 00214 if (sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 00215 p->ourip = sipnet.__ourip; 00216 build_via(p, FALSE); 00217 build_callid_pvt(p); 00218 00219 if (peer->pokeexpire > -1) 00220 ast_sched_del(sched, peer->pokeexpire); 00221 p->relatedpeer = peer; 00222 ast_set_flag(&p->flags[0], SIP_OUTGOING); 00223 #ifdef VOCAL_DATA_HACK 00224 ast_copy_string(p->peername, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->peername)); 00225 transmit_invite(p, SIP_INVITE, FALSE, 2); 00226 #else 00227 transmit_invite(p, SIP_OPTIONS, FALSE, 2); 00228 #endif 00229 gettimeofday(&peer->ps, NULL); 00230 peer->pokeexpire = ast_sched_add(sched, DEFAULT_QUALIFY_MAXMS * 2, sip_poke_noanswer, peer); 00231 00232 return 0; 00233 }
|
|
|
Poke peer (send qualify to check if peer is alive and well).
Definition at line 93 of file sip3_pokedevice.c. References sip_device::pokeexpire, and sip_poke_peer(). 00094 { 00095 struct sip_device *peer = data; 00096 00097 peer->pokeexpire = -1; 00098 sip_poke_peer(peer); 00099 return 0; 00100 }
|