Index: pbx_dundi.c =================================================================== RCS file: /usr/cvsroot/asterisk/pbx/pbx_dundi.c,v retrieving revision 1.12 diff -r1.12 pbx_dundi.c 114a115,120 > static int map_update_interval = 0; > static int map_updates_per_pkt = 45; > static int map_peering_sid = -1; > static int map_contact_sid = -1; > static char map_context[80]; > static struct sockaddr_in map_addr; 2371a2378 > ast_cli(fd, "Order: %s\n", order); 2413,2414c2420,2421 < #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-8.8s %-15.15s\n" < #define FORMAT "%-20.20s %-15.15s %s %-10.10s %-8.8s %-15.15s\n" --- > #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-10.10s %-8.8s %-15.15s\n" > #define FORMAT "%-20.20s %-15.15s %s %-10.10s %-10.10s %-8.8s %-15.15s\n" 2419a2427,2428 > char *order = NULL; > 2429c2438 < ast_cli(fd, FORMAT2, "EID", "Host", "Model", "AvgTime", "Status"); --- > ast_cli(fd, FORMAT2, "EID", "Host", "Model", "Order", "AvgTime", "Status"); 2450a2460,2475 > switch(peer->order) { > case 0: > order = "Primary"; > break; > case 1: > order = "Secondary"; > break; > case 2: > order = "Tertiary"; > break; > case 3: > order = "Quartiary"; > break; > default: > order = "Unknown"; > } 2453c2478 < peer->dynamic ? "(D)" : "(S)", model2str(peer->model), avgms, status); --- > peer->dynamic ? "(D)" : "(S)", model2str(peer->model), order, avgms, status); 2470c2495 < peer->dynamic ? "(D)" : "(S)", model2str(peer->model), avgms, status); --- > peer->dynamic ? "(D)" : "(S)", model2str(peer->model), order, avgms, status); 2714a2740,2895 > static inline char *dstatus_append_long(char *buf, long val) { > val = htonl(val); > memcpy(buf, &val, sizeof(long)); > return (buf + sizeof(long)); > } > > static inline char *dstatus_append_short(char *buf, short val) { > val = htons(val); > memcpy(buf, &val, sizeof(short)); > return (buf + sizeof(short)); > } > > static inline char *dstatus_append_string(char *buf, char *str) { > unsigned short len = (unsigned short)strlen(str); > buf = dstatus_append_short(buf, len); > memcpy(buf, str, len); > return (buf + len); > } > > /* Create a packet for the DUNDi Status Updates */ > static char *dstatus_v2_pkt_header(char *buf, char pkt_type, time_t ts, short seq, short totseq) { > *buf++ = '\003'; > *buf++ = pkt_type; > > /* Timestamp this sequence */ > buf = dstatus_append_long(buf, ts); > > /* Setup sequence headers */ > buf = dstatus_append_short(buf, seq); > buf = dstatus_append_short(buf, totseq); > > /* Append our global EID */ > memcpy(buf, &global_eid, sizeof(global_eid)); > buf += sizeof(global_eid); > > buf = dstatus_append_string(buf, map_context); > > return buf; > } > > static int dundi_xmit_peering(void *data) > { > char buf[1500]; > char *ptr = buf; > short seq = 1, totseq = 0; > int need_send = 0, peer_count = 0; > struct dundi_peer *peer; > time_t send_t = time(NULL); > > /* If we have no where to send, don't bother */ > if(!map_addr.sin_addr.s_addr) { > if(option_verbose) > ast_verbose(VERBOSE_PREFIX_1 "No server to send mapping update to...\n"); > map_peering_sid = ast_sched_add(sched, map_update_interval, dundi_xmit_peering, 0); > return 0; > } > > /* Provide a sequence number for the packet and totals */ > ast_mutex_lock(&peerlock); > for (peer = peers;peer;peer = peer->next) { > if(has_permission(peer->include, map_context) || has_permission(peer->permit, map_context)) { > peer_count++; > need_send = 1; > if(peer_count == map_updates_per_pkt) { > peer_count = 0; > need_send = 0; > totseq++; > } > } > } > totseq += need_send; > > /* Initialize the packet header */ > ptr = dstatus_v2_pkt_header(buf, 1, send_t, seq, totseq); > > /* Include our update interval, in seconds */ > ptr = dstatus_append_short(ptr, map_update_interval/1000); > > /* Include peers/packet configured */ > *ptr++ = (unsigned char)map_updates_per_pkt; > > peer_count = 0; > need_send = 0; > for (peer = peers;peer;peer = peer->next) { > if(!has_permission(peer->include, map_context) && !has_permission(peer->permit, map_context)) > continue; > > peer_count++; > need_send = 1; > > /* Copy the peers EID */ > memcpy(ptr, &peer->eid, sizeof(peer->eid)); > ptr += sizeof(peer->eid); > > /* This is the remote peer */ > *ptr++ = (peer->dynamic?0:1); > memcpy(ptr, &peer->addr.sin_addr.s_addr, sizeof(peer->addr.sin_addr.s_addr)); > ptr += sizeof(peer->addr.sin_addr.s_addr); > > /* Append the model and order */ > *ptr++ = peer->model; > *ptr++ = peer->order; > > /* Do some long encoding of the timings */ > ptr = dstatus_append_long(ptr, peer->maxms); > ptr = dstatus_append_long(ptr, peer->lastms); > ptr = dstatus_append_long(ptr, peer->avgms); > > if(peer_count == map_updates_per_pkt) { /* Okay, it's actually arbitrary */ > peer_count = 0; > need_send = 0; > sendto(netsocket, buf, ptr - buf, 0, (struct sockaddr *)&map_addr, sizeof(map_addr)); > seq++; /* We sent one, so move on */ > > ptr = dstatus_v2_pkt_header(buf, 1, send_t, seq, totseq); > /* Include our update interval, in seconds */ > ptr = dstatus_append_short(ptr, map_update_interval/1000); > > /* Include peers/packet configured */ > *ptr++ = (unsigned char)map_updates_per_pkt; > } > } > > /* If we get here, and haven't sent the packet, send it now */ > if(need_send) > sendto(netsocket, buf, ptr - buf, 0, (struct sockaddr *)&map_addr, sizeof(map_addr)); > > /* Unlock */ > ast_mutex_unlock(&peerlock); > > /* Reschedule yourselves */ > map_peering_sid = ast_sched_add(sched, map_update_interval, dundi_xmit_peering, 0); > return RESULT_SUCCESS; > } > > static int dundi_xmit_contact(void *data) { > char buf[1500]; > char *ptr = buf; > > /* Packet type 2, sent now, 1/1 packets */ > ptr = dstatus_v2_pkt_header(buf, 2, time(NULL), 1, 1); > > ptr = dstatus_append_string(ptr, dept); > ptr = dstatus_append_string(ptr, org); > ptr = dstatus_append_string(ptr, locality); > ptr = dstatus_append_string(ptr, stateprov); > ptr = dstatus_append_string(ptr, country); > ptr = dstatus_append_string(ptr, email); > ptr = dstatus_append_string(ptr, phone); > > sendto(netsocket, buf, ptr - buf, 0, (struct sockaddr *)&map_addr, sizeof(map_addr)); > > map_contact_sid = ast_sched_add(sched, map_update_interval * 5, dundi_xmit_contact, 0); > return RESULT_SUCCESS; > } > 4329a4511,4538 > } else if (!strcasecmp(v->name, "mapserver")) { > hp = ast_gethostbyname(v->value, &he); > if (hp) { > memcpy(&map_addr.sin_addr, hp->h_addr, sizeof(map_addr.sin_addr)); > if (option_verbose > 1) > ast_verbose(VERBOSE_PREFIX_2 "Using mapping server at %s\n", v->value); > } else { > memset(&map_addr.sin_addr, 0, sizeof(map_addr.sin_addr)); > ast_log(LOG_WARNING, "Could not find host '%s' for mapping host\n", v->value); > } > } else if (!strcasecmp(v->name, "mappeers_per_pkt")) { > map_updates_per_pkt = atoi(v->value); > if(map_updates_per_pkt < 1 || map_updates_per_pkt > 45) { > ast_log(LOG_WARNING, "Map updates must be between 1 and 45 inclusive. Setting to 45.\n"); > map_updates_per_pkt = 45; > } > } else if (!strcasecmp(v->name, "mapport")) { > if (option_verbose > 1) > ast_verbose(VERBOSE_PREFIX_2 "Using mapping server at port %d\n", atoi(v->value)); > map_addr.sin_port = htons(atoi(v->value)); > } else if (!strcasecmp(v->name, "mapinterval")) { > map_update_interval = atoi(v->value) * 1000; > if(map_update_interval < 5000 && map_update_interval != 0) > map_update_interval = 5000; > if (option_verbose > 1) > ast_verbose(VERBOSE_PREFIX_2 "Using mapping update interval of %d ms\n", map_update_interval); > } else if(!strcasecmp(v->name, "mapcontext")) { > strncpy(map_context, v->value, sizeof(map_context) - 1); 4355a4565,4575 > > /* Schedule updates */ > if(map_peering_sid > -1) > ast_sched_del(sched, map_peering_sid); > if(map_contact_sid > -1) > ast_sched_del(sched, map_contact_sid); > if(map_update_interval) { > map_peering_sid = ast_sched_add(sched, 1000, dundi_xmit_peering, 0); > map_contact_sid = ast_sched_add(sched, 1000, dundi_xmit_contact, 0); > } > 4404a4625,4630 > /* INADDR_ANY should be 0.0.0.0 */ > map_addr.sin_family = AF_INET; > map_addr.sin_port = ntohs(4525); > map_addr.sin_addr.s_addr = INADDR_ANY; > strncpy(map_context, "open-e164", sizeof(map_context) - 1); > 4458a4685 >