PacketCable COPS. More...
#include "asterisk.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <arpa/inet.h>
#include <signal.h>
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/options.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/cli.h"
#include "asterisk/lock.h"
#include "asterisk/pktccops.h"
Go to the source code of this file.
Data Structures | |
struct | cmts_list |
struct | cops_cmts |
struct | cops_ippool |
struct | copsmsg |
struct | gate_list |
struct | gatespec |
struct | ippool_list |
struct | pktcobj |
Defines | |
#define | AST_API_MODULE |
#define | COPS_HEADER_SIZE 8 |
#define | COPS_OBJECT_HEADER_SIZE 4 |
#define | DEFAULT_COPS_PORT "2126" |
#define | GATE_INFO_OBJ_SIZE 24 |
#define | GATE_SET_OBJ_SIZE 144 |
#define | GATEID_OBJ_SIZE 8 |
#define | PKTCCOPS_DESTROY_CURRENT_GATE |
#define | PKTCCOPS_SCOMMAND_GATE_ALLOC 1 |
#define | PKTCCOPS_SCOMMAND_GATE_ALLOC_ACK 2 |
#define | PKTCCOPS_SCOMMAND_GATE_ALLOC_ERR 3 |
#define | PKTCCOPS_SCOMMAND_GATE_CLOSE 14 |
#define | PKTCCOPS_SCOMMAND_GATE_DELETE 10 |
#define | PKTCCOPS_SCOMMAND_GATE_DELETE_ACK 11 |
#define | PKTCCOPS_SCOMMAND_GATE_DELETE_ERR 12 |
#define | PKTCCOPS_SCOMMAND_GATE_INFO 7 |
#define | PKTCCOPS_SCOMMAND_GATE_INFO_ACK 8 |
#define | PKTCCOPS_SCOMMAND_GATE_INFO_ERR 9 |
#define | PKTCCOPS_SCOMMAND_GATE_OPEN 13 |
#define | PKTCCOPS_SCOMMAND_GATE_SET 4 |
#define | PKTCCOPS_SCOMMAND_GATE_SET_ACK 5 |
#define | PKTCCOPS_SCOMMAND_GATE_SET_ERR 6 |
#define | SENDFLAGS MSG_NOSIGNAL | MSG_DONTWAIT |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
struct cops_gate *AST_OPTIONAL_API_NAME() | ast_pktccops_gate_alloc (int cmd, struct cops_gate *gate, uint32_t mta, uint32_t actcount, float bitrate, uint32_t psize, uint32_t ssip, uint16_t ssport, int(*const got_dq_gi)(struct cops_gate *gate), int(*const gate_remove)(struct cops_gate *gate)) |
static int | cops_connect (char *host, char *port) |
static uint16_t | cops_construct_gate (int cmd, char *p, uint16_t trid, uint32_t mtahost, uint32_t actcount, float rate, uint32_t psizegateid, uint32_t ssip, uint16_t ssport, uint32_t gateid, struct cops_cmts *cmts) |
static uint16_t | cops_constructgatespec (struct gatespec *gs, char *res) |
static void | cops_freemsg (struct copsmsg *p) |
static struct cops_gate * | cops_gate_cmd (int cmd, struct cops_cmts *cmts, uint16_t trid, uint32_t mta, uint32_t actcount, float bitrate, uint32_t psize, uint32_t ssip, uint16_t ssport, struct cops_gate *gate) |
static int | cops_getmsg (int sfd, struct copsmsg *recmsg) |
static int | cops_sendmsg (int sfd, struct copsmsg *sendmsg) |
static void * | do_pktccops (void *data) |
static uint32_t | ftoieeef (float n) |
static int | load_module (void) |
static int | load_pktccops_config (void) |
static int | pktccops_add_ippool (struct cops_ippool *ippool) |
static char * | pktccops_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | pktccops_gatedel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | pktccops_gateset (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | pktccops_show_cmtses (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | pktccops_show_gates (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | pktccops_show_pools (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static void | pktccops_unregister_cmtses (void) |
static void | pktccops_unregister_ippools (void) |
static int | reload_module (void) |
static int | restart_pktc_thread (void) |
static int | unload_module (void) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "PktcCOPS manager for MGCP" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload_module, } |
static struct ast_module_info * | ast_module_info = &__mod_info |
static struct ast_cli_entry | cli_pktccops [] |
static uint16_t | cops_trid = 0 |
static int | gateinfoperiod = 60 |
static int | gatetimeout = 150 |
static uint32_t | keepalive = 60 |
static ast_mutex_t | pktccops_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
static pthread_t | pktccops_thread = AST_PTHREADT_NULL |
static int | pktccopsdebug = 0 |
static int | pktcreload = 0 |
static uint16_t | t1 = 250 |
static uint16_t | t7 = 200 |
static uint16_t | t8 = 300 |
PacketCable COPS.
Definition in file res_pktccops.c.
#define AST_API_MODULE |
Definition at line 64 of file res_pktccops.c.
#define COPS_HEADER_SIZE 8 |
Definition at line 69 of file res_pktccops.c.
Referenced by cops_gate_cmd(), cops_getmsg(), cops_sendmsg(), and do_pktccops().
#define COPS_OBJECT_HEADER_SIZE 4 |
Definition at line 70 of file res_pktccops.c.
Referenced by cops_gate_cmd(), cops_getmsg(), and do_pktccops().
#define DEFAULT_COPS_PORT "2126" |
Definition at line 67 of file res_pktccops.c.
Referenced by load_pktccops_config().
#define GATE_INFO_OBJ_SIZE 24 |
Definition at line 73 of file res_pktccops.c.
Referenced by cops_gate_cmd().
#define GATE_SET_OBJ_SIZE 144 |
Definition at line 71 of file res_pktccops.c.
Referenced by cops_gate_cmd().
#define GATEID_OBJ_SIZE 8 |
Definition at line 72 of file res_pktccops.c.
Referenced by cops_gate_cmd().
#define PKTCCOPS_DESTROY_CURRENT_GATE |
AST_LIST_REMOVE_CURRENT(list); \ if (gate->gate_remove) { \ gate->gate_remove(gate); \ } \ ast_free(gate);
Definition at line 695 of file res_pktccops.c.
Referenced by do_pktccops().
#define PKTCCOPS_SCOMMAND_GATE_ALLOC 1 |
Definition at line 75 of file res_pktccops.c.
#define PKTCCOPS_SCOMMAND_GATE_ALLOC_ACK 2 |
Definition at line 76 of file res_pktccops.c.
#define PKTCCOPS_SCOMMAND_GATE_ALLOC_ERR 3 |
Definition at line 77 of file res_pktccops.c.
#define PKTCCOPS_SCOMMAND_GATE_CLOSE 14 |
Definition at line 88 of file res_pktccops.c.
Referenced by do_pktccops().
#define PKTCCOPS_SCOMMAND_GATE_DELETE 10 |
Definition at line 84 of file res_pktccops.c.
Referenced by cops_construct_gate().
#define PKTCCOPS_SCOMMAND_GATE_DELETE_ACK 11 |
Definition at line 85 of file res_pktccops.c.
Referenced by do_pktccops().
#define PKTCCOPS_SCOMMAND_GATE_DELETE_ERR 12 |
Definition at line 86 of file res_pktccops.c.
#define PKTCCOPS_SCOMMAND_GATE_INFO 7 |
Definition at line 81 of file res_pktccops.c.
Referenced by cops_construct_gate().
#define PKTCCOPS_SCOMMAND_GATE_INFO_ACK 8 |
Definition at line 82 of file res_pktccops.c.
Referenced by do_pktccops().
#define PKTCCOPS_SCOMMAND_GATE_INFO_ERR 9 |
Definition at line 83 of file res_pktccops.c.
Referenced by do_pktccops().
#define PKTCCOPS_SCOMMAND_GATE_OPEN 13 |
Definition at line 87 of file res_pktccops.c.
Referenced by do_pktccops().
#define PKTCCOPS_SCOMMAND_GATE_SET 4 |
Definition at line 78 of file res_pktccops.c.
Referenced by cops_construct_gate().
#define PKTCCOPS_SCOMMAND_GATE_SET_ACK 5 |
Definition at line 79 of file res_pktccops.c.
Referenced by do_pktccops().
#define PKTCCOPS_SCOMMAND_GATE_SET_ERR 6 |
Definition at line 80 of file res_pktccops.c.
Referenced by do_pktccops().
#define SENDFLAGS MSG_NOSIGNAL | MSG_DONTWAIT |
Referenced by cops_sendmsg().
static void __reg_module | ( | void | ) | [static] |
Definition at line 1517 of file res_pktccops.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 1517 of file res_pktccops.c.
struct cops_gate* AST_OPTIONAL_API_NAME() ast_pktccops_gate_alloc | ( | int | cmd, | |
struct cops_gate * | gate, | |||
uint32_t | mta, | |||
uint32_t | actcount, | |||
float | bitrate, | |||
uint32_t | psize, | |||
uint32_t | ssip, | |||
uint16_t | ssport, | |||
int(*)(struct cops_gate *gate) | got_dq_gi, | |||
int(*)(struct cops_gate *gate) | gate_remove | |||
) | [read] |
Definition at line 470 of file res_pktccops.c.
References ast_debug, ast_log(), cops_gate_cmd(), cops_gate::gate_remove, GATE_SET_HAVE_GATEID, cops_gate::gateid, cops_gate::got_dq_gi, LOG_WARNING, and pktcreload.
Referenced by mgcp_alloc_pktcgate(), and mgcp_hangup().
00475 { 00476 while (pktcreload) { 00477 sched_yield(); 00478 } 00479 00480 if (cmd == GATE_SET_HAVE_GATEID && gate) { 00481 ast_debug(3, "------- gate modify gateid 0x%x ssip: 0x%x\n", gate->gateid, ssip); 00482 /* TODO implement it */ 00483 ast_log(LOG_WARNING, "Modify GateID not implemented\n"); 00484 } 00485 00486 if ((gate = cops_gate_cmd(cmd, NULL, cops_trid++, mta, actcount, bitrate, psize, ssip, ssport, gate))) { 00487 ast_debug(3, "COPS: Allocating gate for mta: 0x%x\n", mta); 00488 gate->got_dq_gi = got_dq_gi; 00489 gate->gate_remove = gate_remove; 00490 return(gate); 00491 } else { 00492 ast_debug(3, "COPS: Couldn't allocate gate for mta: 0x%x\n", mta); 00493 return NULL; 00494 } 00495 }
static int cops_connect | ( | char * | host, | |
char * | port | |||
) | [static] |
Definition at line 651 of file res_pktccops.c.
References ast_debug, ast_log(), and LOG_WARNING.
Referenced by do_pktccops().
00652 { 00653 int s, sfd = -1, flags; 00654 struct addrinfo hints; 00655 struct addrinfo *rp; 00656 struct addrinfo *result; 00657 #ifdef HAVE_SO_NOSIGPIPE 00658 int trueval = 1; 00659 #endif 00660 00661 memset(&hints, 0, sizeof(struct addrinfo)); 00662 00663 hints.ai_family = AF_UNSPEC; 00664 hints.ai_socktype = SOCK_STREAM; 00665 hints.ai_flags = 0; 00666 hints.ai_protocol = 0; 00667 00668 s = getaddrinfo(host, port, &hints, &result); 00669 if (s != 0) { 00670 ast_log(LOG_WARNING, "COPS: getaddrinfo: %s\n", gai_strerror(s)); 00671 return -1; 00672 } 00673 00674 for (rp = result; rp != NULL; rp = rp->ai_next) { 00675 sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); 00676 if (sfd == -1) { 00677 ast_log(LOG_WARNING, "Failed socket\n"); 00678 } 00679 flags = fcntl(sfd, F_GETFL); 00680 fcntl(sfd, F_SETFL, flags | O_NONBLOCK); 00681 #ifdef HAVE_SO_NOSIGPIPE 00682 setsockopt(sfd, SOL_SOCKET, SO_NOSIGPIPE, &trueval, sizeof(trueval)); 00683 #endif 00684 connect(sfd, rp->ai_addr, rp->ai_addrlen); 00685 if (sfd == -1) { 00686 ast_log(LOG_WARNING, "Failed connect\n"); 00687 } 00688 } 00689 freeaddrinfo(result); 00690 00691 ast_debug(3, "Connecting to cmts: %s:%s\n", host, port); 00692 return(sfd); 00693 }
static uint16_t cops_construct_gate | ( | int | cmd, | |
char * | p, | |||
uint16_t | trid, | |||
uint32_t | mtahost, | |||
uint32_t | actcount, | |||
float | rate, | |||
uint32_t | psizegateid, | |||
uint32_t | ssip, | |||
uint16_t | ssport, | |||
uint32_t | gateid, | |||
struct cops_cmts * | cmts | |||
) | [static] |
Definition at line 223 of file res_pktccops.c.
References ast_debug, gatespec::b, cops_constructgatespec(), gatespec::diffserv, gatespec::direction, gatespec::dstip, gatespec::dstp, gatespec::flags, ftoieeef(), GATE_DEL, GATE_INFO, GATE_SET_HAVE_GATEID, gatespec::m, gatespec::mm, gatespec::p, PKTCCOPS_SCOMMAND_GATE_DELETE, PKTCCOPS_SCOMMAND_GATE_INFO, PKTCCOPS_SCOMMAND_GATE_SET, gatespec::protocolid, gatespec::r, gatespec::rate, gatespec::s, gatespec::sessionclass, gatespec::srcip, gatespec::srcp, cops_cmts::t1, gatespec::t1, cops_cmts::t7, gatespec::t7, cops_cmts::t8, and gatespec::t8.
Referenced by cops_gate_cmd().
00226 { 00227 struct gatespec gs; 00228 int offset = 0; 00229 00230 ast_debug(3, "CMD: %d\n", cmd); 00231 00232 /* Transaction Identifier 8 octets */ 00233 *(p + offset++) = 0; 00234 *(p + offset++) = 8; /* length */ 00235 *(p + offset++) = 1; /* snum */ 00236 *(p + offset++) = 1; /* stype */ 00237 *((uint16_t *) (p + offset)) = htons(trid); 00238 offset += 2; 00239 *(p + offset++) = 0; 00240 *(p + offset++) = (cmd == GATE_DEL) ? PKTCCOPS_SCOMMAND_GATE_DELETE : (cmd != GATE_INFO) ? PKTCCOPS_SCOMMAND_GATE_SET : PKTCCOPS_SCOMMAND_GATE_INFO; /* 4: GATE-SET, 7: GATE-INFO */ 00241 00242 /*Subscriper Identifier 8 octets */ 00243 *(p + offset++) = 0; 00244 *(p + offset++) = 8; /* length */ 00245 *(p + offset++) = 2; /* snum */ 00246 *(p + offset++) = 1; /* stype */ 00247 *((uint32_t *) (p + offset)) = htonl(mtahost); 00248 offset += 4; 00249 00250 if (cmd == GATE_INFO || cmd == GATE_SET_HAVE_GATEID || cmd == GATE_DEL) { 00251 /* Gate ID 8 Octets */ 00252 *(p + offset++) = 0; 00253 *(p + offset++) = 8; /* length */ 00254 *(p + offset++) = 3; /* snum */ 00255 *(p + offset++) = 1; /* stype */ 00256 *((uint32_t *) (p + offset)) = htonl(gateid); 00257 offset += 4; 00258 if (cmd == GATE_INFO || cmd == GATE_DEL) { 00259 return offset; 00260 } 00261 00262 } 00263 00264 /* Activity Count 8 octets */ 00265 *(p + offset++) = 0; 00266 *(p + offset++) = 8; /* length */ 00267 *(p + offset++) = 4; /* snum */ 00268 *(p + offset++) = 1; /* stype */ 00269 *((uint32_t *) (p + offset)) = htonl(actcount); 00270 offset += 4; 00271 00272 00273 /* Gate Spec 2*60 Octets */ 00274 gs.direction = 0; /* DS */ 00275 gs.protocolid = 17; /* UDP */ 00276 gs.flags = 0; 00277 gs.sessionclass = 1; 00278 gs.srcip = htonl(ssip); 00279 gs.dstip = htonl(mtahost); 00280 gs.srcp = htons(ssport); 00281 gs.dstp = 0; 00282 /* gs.diffserv = 0xa0;*/ 00283 gs.diffserv = 0; 00284 gs.t1 = htons(cmts->t1); 00285 gs.t7 = htons(cmts->t7); 00286 gs.t8 = htons(cmts->t8); 00287 gs.r = ftoieeef(rate); 00288 gs.b = ftoieeef(psizegateid); 00289 gs.p = ftoieeef(rate); 00290 gs.m = htonl((uint32_t) psizegateid); 00291 gs.mm = htonl((uint32_t) psizegateid); 00292 gs.rate = ftoieeef(rate); 00293 gs.s = htonl(800); 00294 00295 00296 *(p + offset) = 0; 00297 offset++; 00298 *(p + offset) = 60; /* length */ 00299 offset++; 00300 *(p + offset) = 5; /* snum */ 00301 offset++; 00302 *(p + offset) = 1; /* stype */ 00303 offset++; 00304 offset += cops_constructgatespec(&gs, p + offset); 00305 00306 00307 gs.direction = 1; /* US */ 00308 gs.srcip = htonl(mtahost); 00309 gs.dstip = htonl(ssip); 00310 gs.srcp = 0; 00311 gs.dstp = htons(ssport); 00312 *(p + offset) = 0; 00313 offset++; 00314 *(p + offset) = 60; /* length */ 00315 offset++; 00316 *(p + offset) = 5; /* snum */ 00317 offset++; 00318 *(p + offset) = 1; /* stype */ 00319 offset++; 00320 offset += cops_constructgatespec(&gs, p + offset); 00321 00322 return(offset); 00323 }
static uint16_t cops_constructgatespec | ( | struct gatespec * | gs, | |
char * | res | |||
) | [static] |
Definition at line 184 of file res_pktccops.c.
References gatespec::b, gatespec::diffserv, gatespec::direction, gatespec::dstip, gatespec::dstp, gatespec::flags, gatespec::m, gatespec::mm, gatespec::p, gatespec::protocolid, gatespec::r, gatespec::rate, gatespec::s, gatespec::sessionclass, gatespec::srcip, gatespec::srcp, gatespec::t1, gatespec::t7, and gatespec::t8.
Referenced by cops_construct_gate().
00185 { 00186 if (res == NULL) { 00187 return 0; 00188 } 00189 00190 *res = (char) gs->direction; 00191 *(res + 1) = (char) gs->protocolid; 00192 *(res + 2) = (char) gs->flags; 00193 *(res + 3) = (char) gs->sessionclass; 00194 00195 *((uint32_t *) (res + 4)) = gs->srcip; 00196 *((uint32_t *) (res + 8)) = gs->dstip; 00197 00198 *((uint16_t *) (res + 12)) = gs->srcp; 00199 *((uint16_t *) (res + 14)) = gs->dstp; 00200 00201 *(res + 16) = (char) gs->diffserv; 00202 *(res + 17) = 0; /* reserved */ 00203 *(res + 18) = 0; /* reserved */ 00204 *(res + 19) = 0; /* reserved */ 00205 00206 *((uint16_t *) (res + 20)) = gs->t1; 00207 *(res + 22) = 0; /* reserved */ 00208 *(res + 23) = 0; /* reserved */ 00209 00210 *((uint16_t *) (res + 24)) = gs->t7; 00211 *((uint16_t *) (res + 26)) = gs->t8; 00212 00213 *((uint32_t *) (res + 28)) = gs->r; 00214 *((uint32_t *) (res + 32)) = gs->b; 00215 *((uint32_t *) (res + 36)) = gs->p; 00216 *((uint32_t *) (res + 40)) = gs->m; 00217 *((uint32_t *) (res + 44)) = gs->mm; 00218 *((uint32_t *) (res + 48)) = gs->rate; 00219 *((uint32_t *) (res + 52)) = gs->s; 00220 return 56; /* length */ 00221 };
static void cops_freemsg | ( | struct copsmsg * | p | ) | [static] |
Definition at line 455 of file res_pktccops.c.
References ast_free, pktcobj::contents, free, copsmsg::msg, pktcobj::next, and copsmsg::object.
Referenced by cops_gate_cmd(), and do_pktccops().
00456 { 00457 struct pktcobj *pnext; 00458 free(p->msg); 00459 p->msg = NULL; 00460 while (p->object != NULL) { 00461 pnext = p->object->next; 00462 ast_free(p->object->contents); 00463 p->object->contents = NULL; 00464 ast_free(p->object); 00465 p->object = pnext; 00466 } 00467 p->object = NULL; 00468 }
static struct cops_gate * cops_gate_cmd | ( | int | cmd, | |
struct cops_cmts * | cmts, | |||
uint16_t | trid, | |||
uint32_t | mta, | |||
uint32_t | actcount, | |||
float | bitrate, | |||
uint32_t | psize, | |||
uint32_t | ssip, | |||
uint16_t | ssport, | |||
struct cops_gate * | gate | |||
) | [static, read] |
Definition at line 497 of file res_pktccops.c.
References ast_calloc, ast_debug, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), copsmsg::clienttype, cops_ippool::cmts, cops_gate::cmts, pktcobj::cnum, pktcobj::contents, cops_construct_gate(), cops_freemsg(), COPS_HEADER_SIZE, COPS_OBJECT_HEADER_SIZE, cops_sendmsg(), pktcobj::ctype, free, GATE_ALLOC_PROGRESS, GATE_DEL, GATE_INFO, GATE_INFO_OBJ_SIZE, GATE_SET, GATE_SET_HAVE_GATEID, GATE_SET_OBJ_SIZE, cops_gate::gateid, GATEID_OBJ_SIZE, cops_cmts::handle, cops_gate::in_transaction, copsmsg::length, pktcobj::length, LOG_WARNING, malloc, copsmsg::msg, cops_cmts::name, pktcobj::next, copsmsg::object, copsmsg::opcode, pktccopsdebug, cops_cmts::sfd, cops_ippool::start, stop, cops_gate::trid, and copsmsg::verflag.
Referenced by ast_pktccops_gate_alloc(), do_pktccops(), pktccops_gatedel(), and pktccops_gateset().
00500 { 00501 struct copsmsg *gateset; 00502 struct cops_gate *new; 00503 struct cops_ippool *ippool; 00504 00505 if (cmd == GATE_DEL) { 00506 if (gate == NULL) { 00507 return NULL; 00508 } else { 00509 cmts = gate->cmts; 00510 } 00511 } 00512 00513 if (!cmts) { 00514 AST_LIST_LOCK(&ippool_list); 00515 AST_LIST_TRAVERSE(&ippool_list, ippool, list) { 00516 if (mta >= ippool->start && mta <= ippool->stop) { 00517 cmts = ippool->cmts; 00518 break; 00519 } 00520 } 00521 AST_LIST_UNLOCK(&ippool_list); 00522 if (!cmts) { 00523 ast_log(LOG_WARNING, "COPS: couldn't find cmts for mta: 0x%x\n", mta); 00524 return NULL; 00525 } 00526 if (cmts->sfd < 0) { 00527 ast_log(LOG_WARNING, "CMTS: %s not connected\n", cmts->name); 00528 return NULL; 00529 } 00530 } 00531 00532 if (cmd == GATE_SET) { 00533 new = ast_calloc(1, sizeof(*new)); 00534 new->gateid = 0; 00535 new->trid = trid; 00536 new->mta = mta; 00537 new->state = GATE_ALLOC_PROGRESS; 00538 new->checked = time(NULL); 00539 new->allocated = time(NULL); 00540 new->cmts = cmts; 00541 new->got_dq_gi = NULL; 00542 new->gate_remove = NULL; 00543 new->gate_open = NULL; 00544 new->tech_pvt = NULL; 00545 new->deltimer = 0; 00546 AST_LIST_LOCK(&gate_list); 00547 AST_LIST_INSERT_HEAD(&gate_list, new, list); 00548 AST_LIST_UNLOCK(&gate_list); 00549 gate = new; 00550 } else { 00551 if (gate) { 00552 gate->trid = trid; 00553 } 00554 } 00555 00556 gate->in_transaction = time(NULL); 00557 00558 if (!(gateset = malloc(sizeof(struct copsmsg)))) { 00559 free(gateset); 00560 return NULL; 00561 } 00562 gateset->msg = NULL; 00563 gateset->verflag = 0x10; 00564 gateset->opcode = 2; /* Decision */ 00565 gateset->clienttype = 0x8008; /* =PacketCable */ 00566 00567 /* Handle object */ 00568 gateset->object = malloc(sizeof(struct pktcobj)); 00569 if (!gateset->object) { 00570 cops_freemsg(gateset); 00571 free(gateset); 00572 return NULL; 00573 } 00574 gateset->object->length = COPS_OBJECT_HEADER_SIZE + 4; 00575 gateset->object->cnum = 1; /* Handle */ 00576 gateset->object->ctype = 1; /* client */ 00577 if (!(gateset->object->contents = malloc(sizeof(uint32_t)))) { 00578 cops_freemsg(gateset); 00579 free(gateset); 00580 return NULL; 00581 } 00582 *((uint32_t *) gateset->object->contents) = htonl(cmts->handle); 00583 00584 /* Context Object */ 00585 if (!(gateset->object->next = malloc(sizeof(struct pktcobj)))) { 00586 cops_freemsg(gateset); 00587 free(gateset); 00588 return NULL; 00589 } 00590 gateset->object->next->length = COPS_OBJECT_HEADER_SIZE + 4; 00591 gateset->object->next->cnum = 2; /* Context */ 00592 gateset->object->next->ctype = 1; /* Context */ 00593 if (!(gateset->object->next->contents = malloc(sizeof(uint32_t)))) { 00594 cops_freemsg(gateset); 00595 free(gateset); 00596 return NULL; 00597 } 00598 *((uint32_t *) gateset->object->next->contents) = htonl(0x00080000); /* R-Type = 8 configuration request, M-Type = 0 */ 00599 00600 /* Decision Object: Flags */ 00601 if (!(gateset->object->next->next = malloc(sizeof(struct pktcobj)))) { 00602 cops_freemsg(gateset); 00603 free(gateset); 00604 return NULL; 00605 } 00606 gateset->object->next->next->length = COPS_OBJECT_HEADER_SIZE + 4; 00607 gateset->object->next->next->cnum = 6; /* Decision */ 00608 gateset->object->next->next->ctype = 1; /* Flags */ 00609 if (!(gateset->object->next->next->contents = malloc(sizeof(uint32_t)))) { 00610 cops_freemsg(gateset); 00611 free(gateset); 00612 return NULL; 00613 } 00614 *((uint32_t *) gateset->object->next->next->contents) = htonl(0x00010001); /* Install, Trigger Error */ 00615 00616 /* Decision Object: Data */ 00617 if (!(gateset->object->next->next->next = malloc(sizeof(struct pktcobj)))) { 00618 cops_freemsg(gateset); 00619 free(gateset); 00620 return NULL; 00621 } 00622 gateset->object->next->next->next->length = COPS_OBJECT_HEADER_SIZE + ((cmd != GATE_INFO && cmd != GATE_DEL) ? GATE_SET_OBJ_SIZE : GATE_INFO_OBJ_SIZE) + ((cmd == GATE_SET_HAVE_GATEID) ? GATEID_OBJ_SIZE : 0); 00623 gateset->object->next->next->next->cnum = 6; /* Decision */ 00624 gateset->object->next->next->next->ctype = 4; /* Decision Data */ 00625 gateset->object->next->next->next->contents = malloc(((cmd != GATE_INFO && cmd != GATE_DEL) ? GATE_SET_OBJ_SIZE : GATE_INFO_OBJ_SIZE) + ((cmd == GATE_SET_HAVE_GATEID) ? GATEID_OBJ_SIZE : 0)); 00626 if (!gateset->object->next->next->next->contents) { 00627 cops_freemsg(gateset); 00628 free(gateset); 00629 return NULL; 00630 } 00631 gateset->object->next->next->next->next = NULL; 00632 00633 gateset->length = COPS_HEADER_SIZE + gateset->object->length + gateset->object->next->length + gateset->object->next->next->length + gateset->object->next->next->next->length; 00634 00635 if ((cmd == GATE_INFO || cmd == GATE_SET_HAVE_GATEID || cmd == GATE_DEL) && gate) { 00636 ast_debug(1, "Construct gate with gateid: 0x%x\n", gate->gateid); 00637 cops_construct_gate(cmd, gateset->object->next->next->next->contents, trid, mta, actcount, bitrate, psize, ssip, ssport, gate->gateid, cmts); 00638 } else { 00639 ast_debug(1, "Construct new gate\n"); 00640 cops_construct_gate(cmd, gateset->object->next->next->next->contents, trid, mta, actcount, bitrate, psize, ssip, ssport, 0, cmts); 00641 } 00642 if (pktccopsdebug) { 00643 ast_debug(3, "send cmd\n"); 00644 } 00645 cops_sendmsg(cmts->sfd, gateset); 00646 cops_freemsg(gateset); 00647 free(gateset); 00648 return gate; 00649 }
static int cops_getmsg | ( | int | sfd, | |
struct copsmsg * | recmsg | |||
) | [static] |
Definition at line 325 of file res_pktccops.c.
References ast_debug, copsmsg::clienttype, pktcobj::cnum, pktcobj::contents, COPS_HEADER_SIZE, COPS_OBJECT_HEADER_SIZE, pktcobj::ctype, len(), pktcobj::length, copsmsg::length, malloc, copsmsg::msg, pktcobj::next, copsmsg::object, copsmsg::opcode, and copsmsg::verflag.
Referenced by do_pktccops().
00326 { 00327 int len, lent; 00328 char buf[COPS_HEADER_SIZE]; 00329 struct pktcobj *pobject = NULL; 00330 uint16_t *ubuf = (uint16_t *) buf; 00331 recmsg->msg = NULL; 00332 recmsg->object = NULL; 00333 len = recv(sfd, buf, COPS_HEADER_SIZE, MSG_DONTWAIT); 00334 if (len < COPS_HEADER_SIZE) { 00335 return len; 00336 } 00337 recmsg->verflag = *buf; 00338 recmsg->opcode = *(buf + 1); 00339 recmsg->clienttype = ntohs(*((uint16_t *) (buf + 2))); 00340 recmsg->length = ntohl(*((uint32_t *) (buf + 4))); 00341 /* Eg KA msg*/ 00342 if (recmsg->clienttype != 0x8008 ) { 00343 if (!(recmsg->msg = malloc(recmsg->length - COPS_HEADER_SIZE))) { 00344 return -1; 00345 } 00346 lent = recv(sfd, recmsg->msg, recmsg->length - COPS_HEADER_SIZE, MSG_DONTWAIT); 00347 if (lent < recmsg->length - COPS_HEADER_SIZE) { 00348 return lent; 00349 } 00350 len += len; 00351 } else { 00352 /* PacketCable Objects */ 00353 while (len < recmsg->length) { 00354 if (len == COPS_HEADER_SIZE) { 00355 /* 1st round */ 00356 if (!(recmsg->object = malloc(sizeof(struct pktcobj)))) { 00357 return -1; 00358 } 00359 pobject = recmsg->object; 00360 } else { 00361 if (!(pobject->next = malloc(sizeof(struct pktcobj)))) { 00362 return -1; 00363 } 00364 pobject = pobject->next; 00365 } 00366 pobject->next = NULL; 00367 lent = recv(sfd, buf, COPS_OBJECT_HEADER_SIZE, MSG_DONTWAIT); 00368 if (lent < COPS_OBJECT_HEADER_SIZE) { 00369 ast_debug(3, "Too short object header len: %i\n", lent); 00370 return lent; 00371 } 00372 len += lent; 00373 pobject->length = ntohs(*ubuf); 00374 pobject->cnum = *(buf + 2); 00375 pobject->ctype = *(buf + 3); 00376 if (!(pobject->contents = malloc(pobject->length - COPS_OBJECT_HEADER_SIZE))) { 00377 return -1; 00378 } 00379 lent = recv(sfd, pobject->contents, pobject->length - COPS_OBJECT_HEADER_SIZE, MSG_DONTWAIT); 00380 if (lent < pobject->length - COPS_OBJECT_HEADER_SIZE) { 00381 ast_debug(3, "Too short object content len: %i\n", lent); 00382 return lent; 00383 } 00384 len += lent; 00385 } 00386 } 00387 return len; 00388 }
static int cops_sendmsg | ( | int | sfd, | |
struct copsmsg * | sendmsg | |||
) | [static] |
Definition at line 390 of file res_pktccops.c.
References ast_debug, ast_log(), copsmsg::clienttype, pktcobj::cnum, pktcobj::contents, COPS_HEADER_SIZE, pktcobj::ctype, errno, free, pktcobj::length, copsmsg::length, LOG_WARNING, malloc, copsmsg::msg, pktcobj::next, copsmsg::object, copsmsg::opcode, SENDFLAGS, and copsmsg::verflag.
Referenced by cops_gate_cmd(), and do_pktccops().
00391 { 00392 char *buf; 00393 int bufpos; 00394 struct pktcobj *pobject; 00395 00396 if (sfd < 0) { 00397 return -1; 00398 } 00399 00400 ast_debug(3, "COPS: sending opcode: %i len: %u\n", sendmsg->opcode, sendmsg->length); 00401 if (sendmsg->length < COPS_HEADER_SIZE) { 00402 ast_log(LOG_WARNING, "COPS: invalid msg size!!!\n"); 00403 return -1; 00404 } 00405 if (!(buf = malloc((size_t) sendmsg->length))) { 00406 return -1; 00407 } 00408 *buf = sendmsg->verflag ; 00409 *(buf + 1) = sendmsg->opcode; 00410 *((uint16_t *)(buf + 2)) = htons(sendmsg->clienttype); 00411 *((uint32_t *)(buf + 4)) = htonl(sendmsg->length); 00412 00413 if (sendmsg->msg != NULL) { 00414 memcpy(buf + COPS_HEADER_SIZE, sendmsg->msg, sendmsg->length - COPS_HEADER_SIZE); 00415 } else if (sendmsg->object != NULL) { 00416 bufpos = 8; 00417 pobject = sendmsg->object; 00418 while(pobject != NULL) { 00419 ast_debug(3, "COPS: Sending Object : cnum: %i ctype %i len: %i\n", pobject->cnum, pobject->ctype, pobject->length); 00420 if (sendmsg->length < bufpos + pobject->length) { 00421 ast_log(LOG_WARNING, "COPS: Invalid msg size len: %u objectlen: %i\n", sendmsg->length, pobject->length); 00422 free(buf); 00423 return -1; 00424 } 00425 *(uint16_t *) (buf + bufpos) = htons(pobject->length); 00426 *(buf + bufpos + 2) = pobject->cnum; 00427 *(buf + bufpos + 3) = pobject->ctype; 00428 if (sendmsg->length < pobject->length + bufpos) { 00429 ast_log(LOG_WARNING, "COPS: Error sum of object len more the msg len %u < %i\n", sendmsg->length, pobject->length + bufpos); 00430 free(buf); 00431 return -1; 00432 } 00433 memcpy((buf + bufpos + 4), pobject->contents, pobject->length - 4); 00434 bufpos += pobject->length; 00435 pobject = pobject->next; 00436 } 00437 } 00438 00439 errno = 0; 00440 #ifdef HAVE_MSG_NOSIGNAL 00441 #define SENDFLAGS MSG_NOSIGNAL | MSG_DONTWAIT 00442 #else 00443 #define SENDFLAGS MSG_DONTWAIT 00444 #endif 00445 if (send(sfd, buf, sendmsg->length, SENDFLAGS) == -1) { 00446 ast_log(LOG_WARNING, "COPS: Send failed errno=%i\n", errno); 00447 free(buf); 00448 return -2; 00449 } 00450 #undef SENDFLAGS 00451 free(buf); 00452 return 0; 00453 }
static void* do_pktccops | ( | void * | data | ) | [static] |
Definition at line 702 of file res_pktccops.c.
References ast_debug, ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_poll, ast_poll_fd_index(), ast_realloc, cops_gate::checked, copsmsg::clienttype, cops_gate::cmts, pktcobj::cnum, pktcobj::contents, cops_connect(), cops_freemsg(), cops_gate_cmd(), cops_getmsg(), COPS_HEADER_SIZE, COPS_OBJECT_HEADER_SIZE, cops_sendmsg(), pktcobj::ctype, cops_gate::deltimer, free, GATE_ALLOC_FAILED, GATE_ALLOCATED, GATE_CLOSED, GATE_CLOSED_ERR, GATE_DEL, GATE_DELETED, GATE_INFO, cops_gate::gate_open, GATE_OPEN, GATE_TIMEOUT, cops_gate::gateid, gateinfoperiod, gatetimeout, cops_gate::got_dq_gi, cops_cmts::handle, cops_cmts::host, cops_gate::in_transaction, cops_cmts::katimer, cops_cmts::keepalive, len(), pktcobj::length, copsmsg::length, load_pktccops_config(), LOG_WARNING, malloc, copsmsg::msg, cops_gate::mta, cops_cmts::name, cops_cmts::need_delete, pktcobj::next, copsmsg::object, copsmsg::opcode, PKTCCOPS_DESTROY_CURRENT_GATE, PKTCCOPS_SCOMMAND_GATE_CLOSE, PKTCCOPS_SCOMMAND_GATE_DELETE_ACK, PKTCCOPS_SCOMMAND_GATE_INFO_ACK, PKTCCOPS_SCOMMAND_GATE_INFO_ERR, PKTCCOPS_SCOMMAND_GATE_OPEN, PKTCCOPS_SCOMMAND_GATE_SET_ACK, PKTCCOPS_SCOMMAND_GATE_SET_ERR, pktccops_unregister_ippools(), pktcreload, cops_cmts::port, cops_cmts::sfd, cops_gate::state, cops_cmts::state, cops_gate::trid, and copsmsg::verflag.
Referenced by restart_pktc_thread().
00703 { 00704 int res, nfds, len; 00705 struct copsmsg *recmsg, *sendmsg; 00706 struct copsmsg recmsgb, sendmsgb; 00707 struct pollfd *pfds = NULL, *tmp; 00708 struct pktcobj *pobject; 00709 struct cops_cmts *cmts; 00710 struct cops_gate *gate; 00711 char *sobjp; 00712 uint16_t snst, sobjlen, scommand, recvtrid, actcount, reason, subreason; 00713 uint32_t gateid, subscrid, pktcerror; 00714 time_t last_exec = 0; 00715 00716 recmsg = &recmsgb; 00717 sendmsg = &sendmsgb; 00718 00719 ast_debug(3, "COPS: thread started\n"); 00720 00721 for (;;) { 00722 ast_free(pfds); 00723 pfds = NULL; 00724 nfds = 0; 00725 AST_LIST_LOCK(&cmts_list); 00726 AST_LIST_TRAVERSE(&cmts_list, cmts, list) { 00727 if (last_exec != time(NULL)) { 00728 if (cmts->state == 2 && cmts->katimer + cmts->keepalive < time(NULL)) { 00729 ast_log(LOG_WARNING, "KA timer (%us) expired cmts: %s\n", cmts->keepalive, cmts->name); 00730 cmts->state = 0; 00731 cmts->katimer = -1; 00732 close(cmts->sfd); 00733 cmts->sfd = -1; 00734 } 00735 } 00736 if (cmts->sfd > 0) { 00737 if (!(tmp = ast_realloc(pfds, (nfds + 1) * sizeof(*pfds)))) { 00738 continue; 00739 } 00740 pfds = tmp; 00741 pfds[nfds].fd = cmts->sfd; 00742 pfds[nfds].events = POLLIN; 00743 pfds[nfds].revents = 0; 00744 nfds++; 00745 } else { 00746 cmts->sfd = cops_connect(cmts->host, cmts->port); 00747 if (cmts->sfd > 0) { 00748 cmts->state = 1; 00749 if (cmts->sfd > 0) { 00750 if (!(tmp = ast_realloc(pfds, (nfds + 1) * sizeof(*pfds)))) { 00751 continue; 00752 } 00753 pfds = tmp; 00754 pfds[nfds].fd = cmts->sfd; 00755 pfds[nfds].events = POLLIN; 00756 pfds[nfds].revents = 0; 00757 nfds++; 00758 } 00759 } 00760 } 00761 } 00762 AST_LIST_UNLOCK(&cmts_list); 00763 00764 if (last_exec != time(NULL)) { 00765 last_exec = time(NULL); 00766 AST_LIST_LOCK(&gate_list); 00767 AST_LIST_TRAVERSE_SAFE_BEGIN(&gate_list, gate, list) { 00768 if (gate) { 00769 if (gate->deltimer && gate->deltimer < time(NULL)) { 00770 gate->deltimer = time(NULL) + 5; 00771 gate->trid = cops_trid++; 00772 cops_gate_cmd(GATE_DEL, gate->cmts, gate->trid, 0, 0, 0, 0, 0, 0, gate); 00773 ast_debug(3, "COPS: requested Gate-Del: CMTS: %s gateid: 0x%x\n", (gate->cmts) ? gate->cmts->name : "null", gate->gateid); 00774 } 00775 if (time(NULL) - gate->checked > gatetimeout) { 00776 ast_debug(3, "COPS: remove from list GATE, CMTS: %s gateid: 0x%x\n", (gate->cmts) ? gate->cmts->name : "null", gate->gateid); 00777 gate->state = GATE_TIMEOUT; 00778 PKTCCOPS_DESTROY_CURRENT_GATE; 00779 } else if (time(NULL) - gate->checked > gateinfoperiod && (gate->state == GATE_ALLOCATED || gate->state == GATE_OPEN)) { 00780 if (gate->cmts && (!gate->in_transaction || ( gate->in_transaction + 5 ) < time(NULL))) { 00781 gate->trid = cops_trid++; 00782 ast_debug(3, "COPS: Gate-Info send to CMTS: %s gateid: 0x%x\n", gate->cmts->name, gate->gateid); 00783 cops_gate_cmd(GATE_INFO, gate->cmts, gate->trid, gate->mta, 0, 0, 0, 0, 0, gate); 00784 } 00785 } 00786 } 00787 } 00788 AST_LIST_TRAVERSE_SAFE_END; 00789 AST_LIST_UNLOCK(&gate_list); 00790 } 00791 00792 if (pktcreload == 2) { 00793 pktcreload = 0; 00794 } 00795 if ((res = ast_poll(pfds, nfds, 1000))) { 00796 AST_LIST_LOCK(&cmts_list); 00797 AST_LIST_TRAVERSE(&cmts_list, cmts, list) { 00798 int idx; 00799 if ((idx = ast_poll_fd_index(pfds, nfds, cmts->sfd)) > -1 && (pfds[idx].revents & POLLIN)) { 00800 len = cops_getmsg(cmts->sfd, recmsg); 00801 if (len > 0) { 00802 ast_debug(3, "COPS: got from %s:\n Header: versflag=0x%.2x opcode=%i clienttype=0x%.4x msglength=%u\n", 00803 cmts->name, (unsigned)recmsg->verflag, 00804 recmsg->opcode, (unsigned)recmsg->clienttype, recmsg->length); 00805 if (recmsg->object != NULL) { 00806 pobject = recmsg->object; 00807 while (pobject != NULL) { 00808 ast_debug(3, " OBJECT: length=%i cnum=%i ctype=%i\n", pobject->length, pobject->cnum, pobject->ctype); 00809 if (recmsg->opcode == 1 && pobject->cnum == 1 && pobject->ctype == 1 ) { 00810 cmts->handle = ntohl(*((uint32_t *) pobject->contents)); 00811 ast_debug(3, " REQ client handle: %u\n", cmts->handle); 00812 cmts->state = 2; 00813 cmts->katimer = time(NULL); 00814 } else if (pobject->cnum == 9 && pobject->ctype == 1) { 00815 sobjp = pobject->contents; 00816 subscrid = 0; 00817 recvtrid = 0; 00818 scommand = 0; 00819 pktcerror = 0; 00820 actcount = 0; 00821 gateid = 0; 00822 reason = 0; 00823 subreason = 0; 00824 while (sobjp < (pobject->contents + pobject->length - 4)) { 00825 sobjlen = ntohs(*((uint16_t *) sobjp)); 00826 snst = ntohs(*((uint16_t *) (sobjp + 2))); 00827 ast_debug(3, " S-Num S-type: 0x%.4x len: %i\n", (unsigned)snst, sobjlen); 00828 if (snst == 0x0101 ) { 00829 recvtrid = ntohs(*((uint16_t *) (sobjp + 4))); 00830 scommand = ntohs(*((uint16_t *) (sobjp + 6))); 00831 ast_debug(3, " Transaction Identifier command: %i trid %i\n", scommand, recvtrid); 00832 } else if (snst == 0x0201) { 00833 subscrid = ntohl(*((uint32_t *) (sobjp + 4))); 00834 ast_debug(3, " Subscriber ID: 0x%.8x\n", subscrid); 00835 } else if (snst == 0x0301) { 00836 gateid = ntohl(*((uint32_t *) (sobjp + 4))); 00837 ast_debug(3, " Gate ID: 0x%x 0x%.8x\n", gateid, gateid); 00838 } else if (snst == 0x0401) { 00839 actcount = ntohs(*((uint16_t *) (sobjp + 6))); 00840 ast_debug(3, " Activity Count: %i\n", actcount); 00841 } else if (snst == 0x0901) { 00842 pktcerror = ntohl(*((uint32_t *) (sobjp + 4))); 00843 ast_debug(3, " PKTC Error: 0x%.8x\n", pktcerror); 00844 } else if (snst == 0x0d01) { 00845 reason = ntohs(*((uint16_t *) (sobjp + 4))); 00846 subreason = ntohs(*((uint16_t *) (sobjp + 6))); 00847 ast_debug(3, " Reason: %d Subreason: %d\n", reason, subreason); 00848 } 00849 sobjp += sobjlen; 00850 if (!sobjlen) 00851 break; 00852 } 00853 if (scommand == PKTCCOPS_SCOMMAND_GATE_CLOSE || scommand == PKTCCOPS_SCOMMAND_GATE_OPEN) { 00854 AST_LIST_LOCK(&gate_list); 00855 AST_LIST_TRAVERSE_SAFE_BEGIN(&gate_list, gate, list) { 00856 if (gate->cmts == cmts && gate->gateid == gateid) { 00857 if (scommand == PKTCCOPS_SCOMMAND_GATE_CLOSE && gate->state != GATE_CLOSED && gate->state != GATE_CLOSED_ERR ) { 00858 ast_debug(3, "COPS Gate Close Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name); 00859 if (subreason) { 00860 gate->state = GATE_CLOSED_ERR; 00861 PKTCCOPS_DESTROY_CURRENT_GATE; 00862 } else { 00863 gate->state = GATE_CLOSED; 00864 PKTCCOPS_DESTROY_CURRENT_GATE; 00865 } 00866 break; 00867 } else if (scommand == PKTCCOPS_SCOMMAND_GATE_OPEN && gate->state == GATE_ALLOCATED) { 00868 ast_debug(3, "COPS Gate Open Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name); 00869 gate->state = GATE_OPEN; 00870 if (gate->gate_open) { 00871 ast_debug(3, "Calling GATE-OPEN callback function\n"); 00872 gate->gate_open(gate); 00873 gate->gate_open = NULL; 00874 } 00875 break; 00876 } 00877 } 00878 } 00879 AST_LIST_TRAVERSE_SAFE_END; 00880 AST_LIST_UNLOCK(&gate_list); 00881 } else if (scommand == PKTCCOPS_SCOMMAND_GATE_SET_ACK || scommand == PKTCCOPS_SCOMMAND_GATE_SET_ERR || scommand == PKTCCOPS_SCOMMAND_GATE_INFO_ACK || scommand == PKTCCOPS_SCOMMAND_GATE_INFO_ERR || scommand == PKTCCOPS_SCOMMAND_GATE_DELETE_ACK) { 00882 AST_LIST_LOCK(&gate_list); 00883 AST_LIST_TRAVERSE_SAFE_BEGIN(&gate_list, gate, list) { 00884 if (gate->cmts == cmts && gate->trid == recvtrid) { 00885 gate->gateid = gateid; 00886 gate->checked = time(NULL); 00887 if (scommand == PKTCCOPS_SCOMMAND_GATE_SET_ACK) { 00888 ast_debug(3, "COPS Gate Set Ack Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name); 00889 gate->state = GATE_ALLOCATED; 00890 if (gate->got_dq_gi) { 00891 gate->got_dq_gi(gate); 00892 gate->got_dq_gi = NULL; 00893 } 00894 } else if (scommand == PKTCCOPS_SCOMMAND_GATE_SET_ERR) { 00895 ast_debug(3, "COPS Gate Set Error TrId: %i ErrorCode: 0x%.8x CMTS: %s\n ", recvtrid, pktcerror, cmts->name); 00896 gate->state = GATE_ALLOC_FAILED; 00897 if (gate->got_dq_gi) { 00898 gate->got_dq_gi(gate); 00899 gate->got_dq_gi = NULL; 00900 } 00901 PKTCCOPS_DESTROY_CURRENT_GATE; 00902 } else if (scommand == PKTCCOPS_SCOMMAND_GATE_INFO_ACK) { 00903 ast_debug(3, "COPS Gate Info Ack Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name); 00904 } else if (scommand == PKTCCOPS_SCOMMAND_GATE_INFO_ERR) { 00905 ast_debug(3, "COPS Gate Info Error Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name); 00906 gate->state = GATE_ALLOC_FAILED; 00907 PKTCCOPS_DESTROY_CURRENT_GATE; 00908 } else if (scommand == PKTCCOPS_SCOMMAND_GATE_DELETE_ACK) { 00909 ast_debug(3, "COPS Gate Deleted Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name); 00910 gate->state = GATE_DELETED; 00911 PKTCCOPS_DESTROY_CURRENT_GATE; 00912 } 00913 gate->in_transaction = 0; 00914 break; 00915 } 00916 } 00917 AST_LIST_TRAVERSE_SAFE_END; 00918 AST_LIST_UNLOCK(&gate_list); 00919 } 00920 } 00921 pobject = pobject->next; 00922 } 00923 } 00924 00925 if (recmsg->opcode == 6 && recmsg->object && recmsg->object->cnum == 11 && recmsg->object->ctype == 1) { 00926 ast_debug(3, "COPS: Client open %s\n", cmts->name); 00927 sendmsg->msg = NULL; 00928 sendmsg->verflag = 0x10; 00929 sendmsg->opcode = 7; /* Client Accept */ 00930 sendmsg->clienttype = 0x8008; /* =PacketCable */ 00931 sendmsg->length = COPS_HEADER_SIZE + COPS_OBJECT_HEADER_SIZE + 4; 00932 sendmsg->object = malloc(sizeof(struct pktcobj)); 00933 sendmsg->object->length = 4 + COPS_OBJECT_HEADER_SIZE; 00934 sendmsg->object->cnum = 10; /* keppalive timer*/ 00935 sendmsg->object->ctype = 1; 00936 sendmsg->object->contents = malloc(sizeof(uint32_t)); 00937 *((uint32_t *) sendmsg->object->contents) = htonl(cmts->keepalive & 0x0000ffff); 00938 sendmsg->object->next = NULL; 00939 cops_sendmsg(cmts->sfd, sendmsg); 00940 cops_freemsg(sendmsg); 00941 } else if (recmsg->opcode == 9) { 00942 ast_debug(3, "COPS: Keepalive Request got echoing back %s\n", cmts->name); 00943 cops_sendmsg(cmts->sfd, recmsg); 00944 cmts->state = 2; 00945 cmts->katimer = time(NULL); 00946 } 00947 } 00948 if (len <= 0) { 00949 ast_debug(3, "COPS: lost connection to %s\n", cmts->name); 00950 close(cmts->sfd); 00951 cmts->sfd = -1; 00952 cmts->state = 0; 00953 } 00954 cops_freemsg(recmsg); 00955 } 00956 } 00957 AST_LIST_UNLOCK(&cmts_list); 00958 } 00959 if (pktcreload) { 00960 ast_debug(3, "Reloading pktccops...\n"); 00961 AST_LIST_LOCK(&gate_list); 00962 AST_LIST_LOCK(&cmts_list); 00963 pktccops_unregister_ippools(); 00964 AST_LIST_TRAVERSE(&cmts_list, cmts, list) { 00965 cmts->need_delete = 1; 00966 } 00967 load_pktccops_config(); 00968 AST_LIST_TRAVERSE_SAFE_BEGIN(&cmts_list, cmts, list) { 00969 if (cmts && cmts->need_delete) { 00970 AST_LIST_TRAVERSE(&gate_list, gate, list) { 00971 if (gate->cmts == cmts) { 00972 ast_debug(3, "Null gate %s\n", gate->cmts->name); 00973 gate->cmts = NULL; 00974 } 00975 gate->in_transaction = 0; 00976 } 00977 AST_LIST_UNLOCK(&gate_list); 00978 ast_debug(3, "removing cmts: %s\n", cmts->name); 00979 if (cmts->sfd > 0) { 00980 close(cmts->sfd); 00981 } 00982 AST_LIST_REMOVE_CURRENT(list); 00983 free(cmts); 00984 } 00985 } 00986 AST_LIST_TRAVERSE_SAFE_END; 00987 AST_LIST_UNLOCK(&cmts_list); 00988 AST_LIST_UNLOCK(&gate_list); 00989 pktcreload = 2; 00990 } 00991 pthread_testcancel(); 00992 } 00993 return NULL; 00994 }
static uint32_t ftoieeef | ( | float | n | ) | [static] |
Definition at line 177 of file res_pktccops.c.
Referenced by cops_construct_gate().
static int load_module | ( | void | ) | [static] |
Definition at line 1466 of file res_pktccops.c.
References ast_cli_register_multiple(), AST_LIST_LOCK, AST_LIST_UNLOCK, AST_MODULE_LOAD_DECLINE, load_pktccops_config(), and restart_pktc_thread().
01467 { 01468 int res; 01469 AST_LIST_LOCK(&cmts_list); 01470 res = load_pktccops_config(); 01471 AST_LIST_UNLOCK(&cmts_list); 01472 if (res == -1) { 01473 return AST_MODULE_LOAD_DECLINE; 01474 } 01475 ast_cli_register_multiple(cli_pktccops, sizeof(cli_pktccops) / sizeof(struct ast_cli_entry)); 01476 restart_pktc_thread(); 01477 return 0; 01478 }
static int load_pktccops_config | ( | void | ) | [static] |
Definition at line 1025 of file res_pktccops.c.
References ast_calloc, ast_category_browse(), ast_config_destroy(), ast_config_load, ast_copy_string(), AST_LIST_INSERT_HEAD, AST_LIST_TRAVERSE, ast_log(), ast_variable_browse(), cops_ippool::cmts, config, DEFAULT_COPS_PORT, f, gateinfoperiod, gatetimeout, cops_cmts::host, cops_cmts::keepalive, LOG_WARNING, cops_cmts::name, ast_variable::name, cops_cmts::need_delete, ast_variable::next, pktccops_add_ippool(), cops_cmts::port, cops_cmts::sfd, cops_ippool::start, cops_cmts::state, cops_ippool::stop, cops_cmts::t1, cops_cmts::t7, cops_cmts::t8, update(), and ast_variable::value.
Referenced by do_pktccops(), and load_module().
01026 { 01027 static char *cfg = "res_pktccops.conf"; 01028 struct ast_config *config; 01029 struct ast_variable *v; 01030 struct cops_cmts *cmts; 01031 struct cops_ippool *new_ippool; 01032 const char *host, *cat, *port; 01033 int update; 01034 int res = 0; 01035 uint16_t t1_temp, t7_temp, t8_temp; 01036 uint32_t keepalive_temp; 01037 unsigned int a,b,c,d,e,f,g,h; 01038 struct ast_flags config_flags = {0}; 01039 01040 if (!(config = ast_config_load(cfg, config_flags))) { 01041 ast_log(LOG_WARNING, "Unable to load config file res_pktccops.conf\n"); 01042 return -1; 01043 } 01044 for (cat = ast_category_browse(config, NULL); cat; cat = ast_category_browse(config, cat)) { 01045 if (!strcmp(cat, "general")) { 01046 for (v = ast_variable_browse(config, cat); v; v = v->next) { 01047 if (!strcasecmp(v->name, "t1")) { 01048 t1 = atoi(v->value); 01049 } else if (!strcasecmp(v->name, "t7")) { 01050 t7 = atoi(v->value); 01051 } else if (!strcasecmp(v->name, "t8")) { 01052 t8 = atoi(v->value); 01053 } else if (!strcasecmp(v->name, "keepalive")) { 01054 keepalive = atoi(v->value); 01055 } else if (!strcasecmp(v->name, "gateinfoperiod")) { 01056 gateinfoperiod = atoi(v->value); 01057 } else if (!strcasecmp(v->name, "gatetimeout")) { 01058 gatetimeout = atoi(v->value); 01059 } else { 01060 ast_log(LOG_WARNING, "Unkown option %s in general section of res_ptkccops.conf\n", v->name); 01061 } 01062 } 01063 } else { 01064 /* Defaults */ 01065 host = NULL; 01066 port = NULL; 01067 t1_temp = t1; 01068 t7_temp = t7; 01069 t8_temp = t8; 01070 keepalive_temp = keepalive; 01071 01072 for (v = ast_variable_browse(config, cat); v; v = v->next) { 01073 if (!strcasecmp(v->name, "host")) { 01074 host = v->value; 01075 } else if (!strcasecmp(v->name, "port")) { 01076 port = v->value; 01077 } else if (!strcasecmp(v->name, "t1")) { 01078 t1_temp = atoi(v->value); 01079 } else if (!strcasecmp(v->name, "t7")) { 01080 t7_temp = atoi(v->value); 01081 } else if (!strcasecmp(v->name, "t8")) { 01082 t8_temp = atoi(v->value); 01083 } else if (!strcasecmp(v->name, "keepalive")) { 01084 keepalive_temp = atoi(v->value); 01085 } else if (!strcasecmp(v->name, "pool")) { 01086 /* we weill parse it in 2nd round */ 01087 } else { 01088 ast_log(LOG_WARNING, "Unkown option %s in res_ptkccops.conf\n", v->name); 01089 } 01090 } 01091 01092 update = 0; 01093 AST_LIST_TRAVERSE(&cmts_list, cmts, list) { 01094 if (!strcmp(cmts->name, cat)) { 01095 update = 1; 01096 break; 01097 } 01098 01099 } 01100 if (!update) { 01101 cmts = ast_calloc(1, sizeof(*cmts)); 01102 if (!cmts) { 01103 res = -1; 01104 break; 01105 } 01106 AST_LIST_INSERT_HEAD(&cmts_list, cmts, list); 01107 } 01108 if (cat) { 01109 ast_copy_string(cmts->name, cat, sizeof(cmts->name)); 01110 } 01111 if (host) { 01112 ast_copy_string(cmts->host, host, sizeof(cmts->host)); 01113 } 01114 if (port) { 01115 ast_copy_string(cmts->port, port, sizeof(cmts->port)); 01116 } else { 01117 ast_copy_string(cmts->port, DEFAULT_COPS_PORT, sizeof(cmts->port)); 01118 } 01119 01120 cmts->t1 = t1_temp; 01121 cmts->t7 = t7_temp; 01122 cmts->t8 = t8_temp; 01123 cmts->keepalive = keepalive_temp; 01124 if (!update) { 01125 cmts->state = 0; 01126 cmts->sfd = -1; 01127 } 01128 cmts->need_delete = 0; 01129 for (v = ast_variable_browse(config, cat); v; v = v->next) { 01130 /* parse ipppol when we have cmts ptr */ 01131 if (!strcasecmp(v->name, "pool")) { 01132 if (sscanf(v->value, "%3u.%3u.%3u.%3u %3u.%3u.%3u.%3u", &a, &b, &c, &d, &e, &f, &g, &h) == 8) { 01133 new_ippool = ast_calloc(1, sizeof(*new_ippool)); 01134 if (!new_ippool) { 01135 res = -1; 01136 break; 01137 } 01138 new_ippool->start = a << 24 | b << 16 | c << 8 | d; 01139 new_ippool->stop = e << 24 | f << 16 | g << 8 | h; 01140 new_ippool->cmts = cmts; 01141 pktccops_add_ippool(new_ippool); 01142 } else { 01143 ast_log(LOG_WARNING, "Invalid ip pool format in res_pktccops.conf\n"); 01144 } 01145 } 01146 } 01147 } 01148 } 01149 ast_config_destroy(config); 01150 return res; 01151 }
static int pktccops_add_ippool | ( | struct cops_ippool * | ippool | ) | [static] |
Definition at line 1423 of file res_pktccops.c.
References AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), and LOG_WARNING.
Referenced by load_pktccops_config().
01424 { 01425 if (ippool) { 01426 AST_LIST_LOCK(&ippool_list); 01427 AST_LIST_INSERT_HEAD(&ippool_list, ippool, list); 01428 AST_LIST_UNLOCK(&ippool_list); 01429 return 0; 01430 } else { 01431 ast_log(LOG_WARNING, "Attempted to register NULL ippool?\n"); 01432 return -1; 01433 } 01434 }
static char* pktccops_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1386 of file res_pktccops.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, pktccopsdebug, and ast_cli_entry::usage.
01387 { 01388 switch (cmd) { 01389 case CLI_INIT: 01390 e->command = "pktccops set debug {on|off}"; 01391 e->usage = 01392 "Usage: pktccops set debug {on|off}\n" 01393 " Turn on/off debuging\n"; 01394 return NULL; 01395 case CLI_GENERATE: 01396 return NULL; 01397 } 01398 01399 if (a->argc != e->args) 01400 return CLI_SHOWUSAGE; 01401 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 01402 pktccopsdebug = 1; 01403 ast_cli(a->fd, "PktcCOPS Debugging Enabled\n"); 01404 } else if (!strncasecmp(a->argv[e->args - 1], "off", 2)) { 01405 pktccopsdebug = 0; 01406 ast_cli(a->fd, "PktcCOPS Debugging Disabled\n"); 01407 } else { 01408 return CLI_SHOWUSAGE; 01409 } 01410 return CLI_SUCCESS; 01411 01412 }
static char* pktccops_gatedel | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1269 of file res_pktccops.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, cops_gate::cmts, ast_cli_entry::command, cops_gate_cmd(), ast_cli_args::fd, GATE_DEL, cops_gate::gateid, cops_cmts::name, and ast_cli_entry::usage.
01270 { 01271 int found = 0; 01272 int trid; 01273 uint32_t gateid; 01274 struct cops_gate *gate; 01275 struct cops_cmts *cmts; 01276 01277 switch (cmd) { 01278 case CLI_INIT: 01279 e->command = "pktccops gatedel"; 01280 e->usage = 01281 "Usage: pktccops gatedel <cmts> <gateid>\n" 01282 " Send Gate-Del to cmts.\n"; 01283 return NULL; 01284 case CLI_GENERATE: 01285 return NULL; 01286 } 01287 01288 if (a->argc < 4) 01289 return CLI_SHOWUSAGE; 01290 01291 AST_LIST_LOCK(&cmts_list); 01292 AST_LIST_TRAVERSE(&cmts_list, cmts, list) { 01293 if (!strcmp(cmts->name, a->argv[2])) { 01294 ast_cli(a->fd, "Found cmts: %s\n", cmts->name); 01295 found = 1; 01296 break; 01297 } 01298 } 01299 AST_LIST_UNLOCK(&cmts_list); 01300 01301 if (!found) 01302 return CLI_SHOWUSAGE; 01303 01304 trid = cops_trid++; 01305 if (!sscanf(a->argv[3], "%x", &gateid)) { 01306 ast_cli(a->fd, "bad gate specification (%s)\n", a->argv[3]); 01307 return CLI_SHOWUSAGE; 01308 } 01309 01310 found = 0; 01311 AST_LIST_LOCK(&gate_list); 01312 AST_LIST_TRAVERSE(&gate_list, gate, list) { 01313 if (gate->gateid == gateid && gate->cmts == cmts) { 01314 found = 1; 01315 break; 01316 } 01317 } 01318 01319 if (!found) { 01320 ast_cli(a->fd, "gate not found: %s\n", a->argv[3]); 01321 return CLI_SHOWUSAGE; 01322 } 01323 01324 AST_LIST_UNLOCK(&gate_list); 01325 cops_gate_cmd(GATE_DEL, cmts, trid, 0, 0, 0, 0, 0, 0, gate); 01326 return CLI_SUCCESS; 01327 }
static char* pktccops_gateset | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1329 of file res_pktccops.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, cops_gate_cmd(), ast_cli_args::fd, GATE_SET, cops_cmts::name, and ast_cli_entry::usage.
01330 { 01331 int foundcmts = 0; 01332 int trid; 01333 unsigned int an,bn,cn,dn; 01334 uint32_t mta, ssip; 01335 struct cops_cmts *cmts; 01336 01337 switch (cmd) { 01338 case CLI_INIT: 01339 e->command = "pktccops gateset"; 01340 e->usage = 01341 "Usage: pktccops gateset <cmts> <mta> <acctcount> <bitrate> <packet size> <switch ip> <switch port>\n" 01342 " Send Gate-Set to cmts.\n"; 01343 return NULL; 01344 case CLI_GENERATE: 01345 return NULL; 01346 } 01347 01348 if (a->argc < 9) 01349 return CLI_SHOWUSAGE; 01350 01351 if (!strcmp(a->argv[2], "null")) { 01352 cmts = NULL; 01353 } else { 01354 AST_LIST_LOCK(&cmts_list); 01355 AST_LIST_TRAVERSE(&cmts_list, cmts, list) { 01356 if (!strcmp(cmts->name, a->argv[2])) { 01357 ast_cli(a->fd, "Found cmts: %s\n", cmts->name); 01358 foundcmts = 1; 01359 break; 01360 } 01361 } 01362 AST_LIST_UNLOCK(&cmts_list); 01363 if (!foundcmts) { 01364 ast_cli(a->fd, "CMTS not found: %s\n", a->argv[2]); 01365 return CLI_SHOWUSAGE; 01366 } 01367 } 01368 01369 trid = cops_trid++; 01370 if (sscanf(a->argv[3], "%3u.%3u.%3u.%3u", &an, &bn, &cn, &dn) != 4) { 01371 ast_cli(a->fd, "MTA specification (%s) does not look like an ipaddr\n", a->argv[3]); 01372 return CLI_SHOWUSAGE; 01373 } 01374 mta = an << 24 | bn << 16 | cn << 8 | dn; 01375 01376 if (sscanf(a->argv[7], "%3u.%3u.%3u.%3u", &an, &bn, &cn, &dn) != 4) { 01377 ast_cli(a->fd, "SSIP specification (%s) does not look like an ipaddr\n", a->argv[7]); 01378 return CLI_SHOWUSAGE; 01379 } 01380 ssip = an << 24 | bn << 16 | cn << 8 | dn; 01381 01382 cops_gate_cmd(GATE_SET, cmts, trid, mta, atoi(a->argv[4]), atof(a->argv[5]), atoi(a->argv[6]), ssip, atoi(a->argv[8]), NULL); 01383 return CLI_SUCCESS; 01384 }
static char* pktccops_show_cmtses | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1153 of file res_pktccops.c.
References ast_cli(), ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, cops_cmts::host, cops_cmts::katimer, cops_cmts::name, cops_cmts::port, cops_cmts::state, and ast_cli_entry::usage.
01154 { 01155 struct cops_cmts *cmts; 01156 char statedesc[16]; 01157 int katimer; 01158 01159 switch(cmd) { 01160 case CLI_INIT: 01161 e->command = "pktccops show cmtses"; 01162 e->usage = 01163 "Usage: pktccops show cmtses\n" 01164 " List PacketCable COPS CMTSes.\n"; 01165 01166 return NULL; 01167 case CLI_GENERATE: 01168 return NULL; 01169 } 01170 01171 ast_cli(a->fd, "%-16s %-24s %-12s %7s\n", "Name ", "Host ", "Status ", "KA timer "); 01172 ast_cli(a->fd, "%-16s %-24s %-12s %7s\n", "------------", "--------------------", "----------", "-----------"); 01173 AST_LIST_LOCK(&cmts_list); 01174 AST_LIST_TRAVERSE(&cmts_list, cmts, list) { 01175 katimer = -1; 01176 if (cmts->state == 2) { 01177 ast_copy_string(statedesc, "Connected", sizeof(statedesc)); 01178 katimer = (int) (time(NULL) - cmts->katimer); 01179 } else if (cmts->state == 1) { 01180 ast_copy_string(statedesc, "Connecting", sizeof(statedesc)); 01181 } else { 01182 ast_copy_string(statedesc, "N/A", sizeof(statedesc)); 01183 } 01184 ast_cli(a->fd, "%-16s %-15s:%-8s %-12s %-7d\n", cmts->name, cmts->host, cmts->port, statedesc, katimer); 01185 } 01186 AST_LIST_UNLOCK(&cmts_list); 01187 return CLI_SUCCESS; 01188 }
static char* pktccops_show_gates | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1190 of file res_pktccops.c.
References cops_gate::allocated, ast_cli(), ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, cops_gate::checked, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, cops_gate::cmts, ast_cli_entry::command, ast_cli_args::fd, GATE_ALLOC_FAILED, GATE_ALLOC_PROGRESS, GATE_ALLOCATED, GATE_CLOSED, GATE_CLOSED_ERR, GATE_DELETED, GATE_OPEN, cops_gate::gateid, cops_gate::in_transaction, cops_gate::mta, cops_cmts::name, cops_gate::state, and ast_cli_entry::usage.
01191 { 01192 struct cops_gate *gate; 01193 char state_desc[16]; 01194 01195 switch(cmd) { 01196 case CLI_INIT: 01197 e->command = "pktccops show gates"; 01198 e->usage = 01199 "Usage: pktccops show gates\n" 01200 " List PacketCable COPS GATEs.\n"; 01201 01202 return NULL; 01203 case CLI_GENERATE: 01204 return NULL; 01205 } 01206 01207 ast_cli(a->fd, "%-16s %-12s %-12s %-10s %-10s %-10s\n" ,"CMTS", "Gate-Id","MTA", "Status", "AllocTime", "CheckTime"); 01208 ast_cli(a->fd, "%-16s %-12s %-12s %-10s %-10s %-10s\n" ,"--------------" ,"----------", "----------", "--------", "--------", "--------\n"); 01209 AST_LIST_LOCK(&cmts_list); 01210 AST_LIST_LOCK(&gate_list); 01211 AST_LIST_TRAVERSE(&gate_list, gate, list) { 01212 if (gate->state == GATE_ALLOC_FAILED) { 01213 ast_copy_string(state_desc, "Failed", sizeof(state_desc)); 01214 } else if (gate->state == GATE_ALLOC_PROGRESS) { 01215 ast_copy_string(state_desc, "In Progress", sizeof(state_desc)); 01216 } else if (gate->state == GATE_ALLOCATED) { 01217 ast_copy_string(state_desc, "Allocated", sizeof(state_desc)); 01218 } else if (gate->state == GATE_CLOSED) { 01219 ast_copy_string(state_desc, "Closed", sizeof(state_desc)); 01220 } else if (gate->state == GATE_CLOSED_ERR) { 01221 ast_copy_string(state_desc, "ClosedErr", sizeof(state_desc)); 01222 } else if (gate->state == GATE_OPEN) { 01223 ast_copy_string(state_desc, "Open", sizeof(state_desc)); 01224 } else if (gate->state == GATE_DELETED) { 01225 ast_copy_string(state_desc, "Deleted", sizeof(state_desc)); 01226 } else { 01227 ast_copy_string(state_desc, "N/A", sizeof(state_desc)); 01228 } 01229 01230 ast_cli(a->fd, "%-16s 0x%.8x 0x%08x %-10s %10i %10i %u\n", (gate->cmts) ? gate->cmts->name : "null" , gate->gateid, gate->mta, 01231 state_desc, (int) (time(NULL) - gate->allocated), (gate->checked) ? (int) (time(NULL) - gate->checked) : 0, (unsigned int) gate->in_transaction); 01232 } 01233 AST_LIST_UNLOCK(&cmts_list); 01234 AST_LIST_UNLOCK(&gate_list); 01235 return CLI_SUCCESS; 01236 }
static char* pktccops_show_pools | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1238 of file res_pktccops.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, cops_ippool::cmts, ast_cli_entry::command, ast_cli_args::fd, cops_cmts::name, cops_ippool::start, cops_ippool::stop, stop, and ast_cli_entry::usage.
01239 { 01240 struct cops_ippool *ippool; 01241 char start[32]; 01242 char stop[32]; 01243 01244 switch(cmd) { 01245 case CLI_INIT: 01246 e->command = "pktccops show pools"; 01247 e->usage = 01248 "Usage: pktccops show pools\n" 01249 " List PacketCable COPS ip pools of MTAs.\n"; 01250 01251 return NULL; 01252 case CLI_GENERATE: 01253 return NULL; 01254 } 01255 01256 ast_cli(a->fd, "%-16s %-18s %-7s\n", "Start ", "Stop ", "CMTS "); 01257 ast_cli(a->fd, "%-16s %-18s %-7s\n", "----------", "----------", "--------"); 01258 AST_LIST_LOCK(&ippool_list); 01259 AST_LIST_TRAVERSE(&ippool_list, ippool, list) { 01260 snprintf(start, sizeof(start), "%3u.%3u.%3u.%3u", ippool->start >> 24, (ippool->start >> 16) & 0x000000ff, (ippool->start >> 8) & 0x000000ff, ippool->start & 0x000000ff); 01261 01262 snprintf(stop, sizeof(stop), "%3u.%3u.%3u.%3u", ippool->stop >> 24, (ippool->stop >> 16) & 0x000000ff, (ippool->stop >> 8) & 0x000000ff, ippool->stop & 0x000000ff); 01263 ast_cli(a->fd, "%-16s %-18s %-16s\n", start, stop, ippool->cmts->name); 01264 } 01265 AST_LIST_UNLOCK(&ippool_list); 01266 return CLI_SUCCESS; 01267 }
static void pktccops_unregister_cmtses | ( | void | ) | [static] |
Definition at line 1436 of file res_pktccops.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free, and cops_cmts::sfd.
Referenced by unload_module().
01437 { 01438 struct cops_cmts *cmts; 01439 struct cops_gate *gate; 01440 AST_LIST_LOCK(&cmts_list); 01441 while ((cmts = AST_LIST_REMOVE_HEAD(&cmts_list, list))) { 01442 if (cmts->sfd > 0) { 01443 close(cmts->sfd); 01444 } 01445 free(cmts); 01446 } 01447 AST_LIST_UNLOCK(&cmts_list); 01448 01449 AST_LIST_LOCK(&gate_list); 01450 while ((gate = AST_LIST_REMOVE_HEAD(&gate_list, list))) { 01451 free(gate); 01452 } 01453 AST_LIST_UNLOCK(&gate_list); 01454 }
static void pktccops_unregister_ippools | ( | void | ) | [static] |
Definition at line 1456 of file res_pktccops.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free.
Referenced by do_pktccops(), and unload_module().
01457 { 01458 struct cops_ippool *ippool; 01459 AST_LIST_LOCK(&ippool_list); 01460 while ((ippool = AST_LIST_REMOVE_HEAD(&ippool_list, list))) { 01461 free(ippool); 01462 } 01463 AST_LIST_UNLOCK(&ippool_list); 01464 }
static int reload_module | ( | void | ) | [static] |
Definition at line 1502 of file res_pktccops.c.
References ast_log(), LOG_NOTICE, and pktcreload.
01503 { 01504 /* Prohibit unloading */ 01505 if (pktcreload) { 01506 ast_log(LOG_NOTICE, "Previous reload in progress, please wait!\n"); 01507 return -1; 01508 } 01509 pktcreload = 1; 01510 return 0; 01511 }
static int restart_pktc_thread | ( | void | ) | [static] |
Definition at line 996 of file res_pktccops.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_pktccops(), LOG_ERROR, LOG_WARNING, and pktccops_lock.
Referenced by load_module().
00997 { 00998 if (pktccops_thread == AST_PTHREADT_STOP) { 00999 return 0; 01000 } 01001 if (ast_mutex_lock(&pktccops_lock)) { 01002 ast_log(LOG_WARNING, "Unable to lock pktccops\n"); 01003 return -1; 01004 } 01005 if (pktccops_thread == pthread_self()) { 01006 ast_mutex_unlock(&pktccops_lock); 01007 ast_log(LOG_WARNING, "Cannot kill myself\n"); 01008 return -1; 01009 } 01010 if (pktccops_thread != AST_PTHREADT_NULL) { 01011 /* Wake up the thread */ 01012 pthread_kill(pktccops_thread, SIGURG); 01013 } else { 01014 /* Start a new monitor */ 01015 if (ast_pthread_create_background(&pktccops_thread, NULL, do_pktccops, NULL) < 0) { 01016 ast_mutex_unlock(&pktccops_lock); 01017 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 01018 return -1; 01019 } 01020 } 01021 ast_mutex_unlock(&pktccops_lock); 01022 return 0; 01023 }
static int unload_module | ( | void | ) | [static] |
Definition at line 1480 of file res_pktccops.c.
References ast_cli_unregister_multiple(), ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_PTHREADT_STOP, LOG_ERROR, pktccops_lock, pktccops_unregister_cmtses(), and pktccops_unregister_ippools().
01481 { 01482 if (!ast_mutex_lock(&pktccops_lock)) { 01483 if ((pktccops_thread != AST_PTHREADT_NULL) && (pktccops_thread != AST_PTHREADT_STOP)) { 01484 pthread_cancel(pktccops_thread); 01485 pthread_kill(pktccops_thread, SIGURG); 01486 pthread_join(pktccops_thread, NULL); 01487 } 01488 pktccops_thread = AST_PTHREADT_STOP; 01489 ast_mutex_unlock(&pktccops_lock); 01490 } else { 01491 ast_log(LOG_ERROR, "Unable to lock the pktccops_thread\n"); 01492 return -1; 01493 } 01494 01495 ast_cli_unregister_multiple(cli_pktccops, sizeof(cli_pktccops) / sizeof(struct ast_cli_entry)); 01496 pktccops_unregister_cmtses(); 01497 pktccops_unregister_ippools(); 01498 pktccops_thread = AST_PTHREADT_NULL; 01499 return 0; 01500 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "PktcCOPS manager for MGCP" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload_module, } [static] |
Definition at line 1517 of file res_pktccops.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1517 of file res_pktccops.c.
struct ast_cli_entry cli_pktccops[] [static] |
Definition at line 1414 of file res_pktccops.c.
uint16_t cops_trid = 0 [static] |
Definition at line 92 of file res_pktccops.c.
int gateinfoperiod = 60 [static] |
Definition at line 165 of file res_pktccops.c.
Referenced by do_pktccops(), and load_pktccops_config().
int gatetimeout = 150 [static] |
Definition at line 166 of file res_pktccops.c.
Referenced by do_pktccops(), and load_pktccops_config().
uint32_t keepalive = 60 [static] |
Definition at line 162 of file res_pktccops.c.
ast_mutex_t pktccops_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 90 of file res_pktccops.c.
Referenced by restart_pktc_thread(), and unload_module().
pthread_t pktccops_thread = AST_PTHREADT_NULL [static] |
Definition at line 91 of file res_pktccops.c.
int pktccopsdebug = 0 [static] |
Definition at line 163 of file res_pktccops.c.
Referenced by cops_gate_cmd(), and pktccops_debug().
int pktcreload = 0 [static] |
Definition at line 164 of file res_pktccops.c.
Referenced by ast_pktccops_gate_alloc(), do_pktccops(), and reload_module().
uint16_t t1 = 250 [static] |
Definition at line 159 of file res_pktccops.c.
Referenced by dahdi_bridge(), and is_prefix().
uint16_t t7 = 200 [static] |
Definition at line 160 of file res_pktccops.c.
uint16_t t8 = 300 [static] |
Definition at line 161 of file res_pktccops.c.