#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) |
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 |
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.
#define GATE_INFO_OBJ_SIZE 24 |
#define GATE_SET_OBJ_SIZE 144 |
#define GATEID_OBJ_SIZE 8 |
#define PKTCCOPS_DESTROY_CURRENT_GATE |
Value:
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 |
#define PKTCCOPS_SCOMMAND_GATE_DELETE 10 |
#define PKTCCOPS_SCOMMAND_GATE_DELETE_ACK 11 |
#define PKTCCOPS_SCOMMAND_GATE_DELETE_ERR 12 |
Definition at line 86 of file res_pktccops.c.
#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 |
Referenced by cops_sendmsg().
static void __reg_module | ( | void | ) | [static] |
Definition at line 1516 of file res_pktccops.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 1516 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 | |||
) |
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] |
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_gate::cmts, cops_ippool::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, cops_cmts::list, 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: %i\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: %i 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 %i < %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, cops_cmts::list, 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 (%is) 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=%i\n", 00803 cmts->name, recmsg->verflag, recmsg->opcode, recmsg->clienttype, recmsg->length); 00804 if (recmsg->object != NULL) { 00805 pobject = recmsg->object; 00806 while (pobject != NULL) { 00807 ast_debug(3, " OBJECT: length=%i cnum=%i ctype=%i\n", pobject->length, pobject->cnum, pobject->ctype); 00808 if (recmsg->opcode == 1 && pobject->cnum == 1 && pobject->ctype == 1 ) { 00809 cmts->handle = ntohl(*((uint32_t *) pobject->contents)); 00810 ast_debug(3, " REQ client handle: %i\n", cmts->handle); 00811 cmts->state = 2; 00812 cmts->katimer = time(NULL); 00813 } else if (pobject->cnum == 9 && pobject->ctype == 1) { 00814 sobjp = pobject->contents; 00815 subscrid = 0; 00816 recvtrid = 0; 00817 scommand = 0; 00818 pktcerror = 0; 00819 actcount = 0; 00820 gateid = 0; 00821 reason = 0; 00822 subreason = 0; 00823 while (sobjp < (pobject->contents + pobject->length - 4)) { 00824 sobjlen = ntohs(*((uint16_t *) sobjp)); 00825 snst = ntohs(*((uint16_t *) (sobjp + 2))); 00826 ast_debug(3, " S-Num S-type: 0x%.4x len: %i\n", snst, sobjlen); 00827 if (snst == 0x0101 ) { 00828 recvtrid = ntohs(*((uint16_t *) (sobjp + 4))); 00829 scommand = ntohs(*((uint16_t *) (sobjp + 6))); 00830 ast_debug(3, " Transaction Identifier command: %i trid %i\n", scommand, recvtrid); 00831 } else if (snst == 0x0201) { 00832 subscrid = ntohl(*((uint32_t *) (sobjp + 4))); 00833 ast_debug(3, " Subscriber ID: 0x%.8x\n", subscrid); 00834 } else if (snst == 0x0301) { 00835 gateid = ntohl(*((uint32_t *) (sobjp + 4))); 00836 ast_debug(3, " Gate ID: 0x%x 0x%.8x\n", gateid, gateid); 00837 } else if (snst == 0x0401) { 00838 actcount = ntohs(*((uint16_t *) (sobjp + 6))); 00839 ast_debug(3, " Activity Count: %i\n", actcount); 00840 } else if (snst == 0x0901) { 00841 pktcerror = ntohl(*((uint32_t *) (sobjp + 4))); 00842 ast_debug(3, " PKTC Error: 0x%.8x\n", pktcerror); 00843 } else if (snst == 0x0d01) { 00844 reason = ntohs(*((uint16_t *) (sobjp + 4))); 00845 subreason = ntohs(*((uint16_t *) (sobjp + 6))); 00846 ast_debug(3, " Reason: %u Subreason: %u\n", reason, subreason); 00847 } 00848 sobjp += sobjlen; 00849 if (!sobjlen) 00850 break; 00851 } 00852 if (scommand == PKTCCOPS_SCOMMAND_GATE_CLOSE || scommand == PKTCCOPS_SCOMMAND_GATE_OPEN) { 00853 AST_LIST_LOCK(&gate_list); 00854 AST_LIST_TRAVERSE_SAFE_BEGIN(&gate_list, gate, list) { 00855 if (gate->cmts == cmts && gate->gateid == gateid) { 00856 if (scommand == PKTCCOPS_SCOMMAND_GATE_CLOSE && gate->state != GATE_CLOSED && gate->state != GATE_CLOSED_ERR ) { 00857 ast_debug(3, "COPS Gate Close Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name); 00858 if (subreason) { 00859 gate->state = GATE_CLOSED_ERR; 00860 PKTCCOPS_DESTROY_CURRENT_GATE; 00861 } else { 00862 gate->state = GATE_CLOSED; 00863 PKTCCOPS_DESTROY_CURRENT_GATE; 00864 } 00865 break; 00866 } else if (scommand == PKTCCOPS_SCOMMAND_GATE_OPEN && gate->state == GATE_ALLOCATED) { 00867 ast_debug(3, "COPS Gate Open Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name); 00868 gate->state = GATE_OPEN; 00869 if (gate->gate_open) { 00870 ast_debug(3, "Calling GATE-OPEN callback function\n"); 00871 gate->gate_open(gate); 00872 gate->gate_open = NULL; 00873 } 00874 break; 00875 } 00876 } 00877 } 00878 AST_LIST_TRAVERSE_SAFE_END; 00879 AST_LIST_UNLOCK(&gate_list); 00880 } 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) { 00881 AST_LIST_LOCK(&gate_list); 00882 AST_LIST_TRAVERSE_SAFE_BEGIN(&gate_list, gate, list) { 00883 if (gate->cmts == cmts && gate->trid == recvtrid) { 00884 gate->gateid = gateid; 00885 gate->checked = time(NULL); 00886 if (scommand == PKTCCOPS_SCOMMAND_GATE_SET_ACK) { 00887 ast_debug(3, "COPS Gate Set Ack Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name); 00888 gate->state = GATE_ALLOCATED; 00889 if (gate->got_dq_gi) { 00890 gate->got_dq_gi(gate); 00891 gate->got_dq_gi = NULL; 00892 } 00893 } else if (scommand == PKTCCOPS_SCOMMAND_GATE_SET_ERR) { 00894 ast_debug(3, "COPS Gate Set Error TrId: %i ErrorCode: 0x%.8x CMTS: %s\n ", recvtrid, pktcerror, cmts->name); 00895 gate->state = GATE_ALLOC_FAILED; 00896 if (gate->got_dq_gi) { 00897 gate->got_dq_gi(gate); 00898 gate->got_dq_gi = NULL; 00899 } 00900 PKTCCOPS_DESTROY_CURRENT_GATE; 00901 } else if (scommand == PKTCCOPS_SCOMMAND_GATE_INFO_ACK) { 00902 ast_debug(3, "COPS Gate Info Ack Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name); 00903 } else if (scommand == PKTCCOPS_SCOMMAND_GATE_INFO_ERR) { 00904 ast_debug(3, "COPS Gate Info Error Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name); 00905 gate->state = GATE_ALLOC_FAILED; 00906 PKTCCOPS_DESTROY_CURRENT_GATE; 00907 } else if (scommand == PKTCCOPS_SCOMMAND_GATE_DELETE_ACK) { 00908 ast_debug(3, "COPS Gate Deleted Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name); 00909 gate->state = GATE_DELETED; 00910 PKTCCOPS_DESTROY_CURRENT_GATE; 00911 } 00912 gate->in_transaction = 0; 00913 break; 00914 } 00915 } 00916 AST_LIST_TRAVERSE_SAFE_END; 00917 AST_LIST_UNLOCK(&gate_list); 00918 } 00919 } 00920 pobject = pobject->next; 00921 } 00922 } 00923 00924 if (recmsg->opcode == 6 && recmsg->object && recmsg->object->cnum == 11 && recmsg->object->ctype == 1) { 00925 ast_debug(3, "COPS: Client open %s\n", cmts->name); 00926 sendmsg->msg = NULL; 00927 sendmsg->verflag = 0x10; 00928 sendmsg->opcode = 7; /* Client Accept */ 00929 sendmsg->clienttype = 0x8008; /* =PacketCable */ 00930 sendmsg->length = COPS_HEADER_SIZE + COPS_OBJECT_HEADER_SIZE + 4; 00931 sendmsg->object = malloc(sizeof(struct pktcobj)); 00932 sendmsg->object->length = 4 + COPS_OBJECT_HEADER_SIZE; 00933 sendmsg->object->cnum = 10; /* keppalive timer*/ 00934 sendmsg->object->ctype = 1; 00935 sendmsg->object->contents = malloc(sizeof(uint32_t)); 00936 *((uint32_t *) sendmsg->object->contents) = htonl(cmts->keepalive & 0x0000ffff); 00937 sendmsg->object->next = NULL; 00938 cops_sendmsg(cmts->sfd, sendmsg); 00939 cops_freemsg(sendmsg); 00940 } else if (recmsg->opcode == 9) { 00941 ast_debug(3, "COPS: Keepalive Request got echoing back %s\n", cmts->name); 00942 cops_sendmsg(cmts->sfd, recmsg); 00943 cmts->state = 2; 00944 cmts->katimer = time(NULL); 00945 } 00946 } 00947 if (len <= 0) { 00948 ast_debug(3, "COPS: lost connection to %s\n", cmts->name); 00949 close(cmts->sfd); 00950 cmts->sfd = -1; 00951 cmts->state = 0; 00952 } 00953 cops_freemsg(recmsg); 00954 } 00955 } 00956 AST_LIST_UNLOCK(&cmts_list); 00957 } 00958 if (pktcreload) { 00959 ast_debug(3, "Reloading pktccops...\n"); 00960 AST_LIST_LOCK(&gate_list); 00961 AST_LIST_LOCK(&cmts_list); 00962 pktccops_unregister_ippools(); 00963 AST_LIST_TRAVERSE(&cmts_list, cmts, list) { 00964 cmts->need_delete = 1; 00965 } 00966 load_pktccops_config(); 00967 AST_LIST_TRAVERSE_SAFE_BEGIN(&cmts_list, cmts, list) { 00968 if (cmts && cmts->need_delete) { 00969 AST_LIST_TRAVERSE(&gate_list, gate, list) { 00970 if (gate->cmts == cmts) { 00971 ast_debug(3, "Null gate %s\n", gate->cmts->name); 00972 gate->cmts = NULL; 00973 } 00974 gate->in_transaction = 0; 00975 } 00976 AST_LIST_UNLOCK(&gate_list); 00977 ast_debug(3, "removing cmts: %s\n", cmts->name); 00978 if (cmts->sfd > 0) { 00979 close(cmts->sfd); 00980 } 00981 AST_LIST_REMOVE_CURRENT(list); 00982 free(cmts); 00983 } 00984 } 00985 AST_LIST_TRAVERSE_SAFE_END; 00986 AST_LIST_UNLOCK(&cmts_list); 00987 AST_LIST_UNLOCK(&gate_list); 00988 pktcreload = 2; 00989 } 00990 pthread_testcancel(); 00991 } 00992 return NULL; 00993 }
static uint32_t ftoieeef | ( | float | n | ) | [static] |
static int load_module | ( | void | ) | [static] |
Definition at line 1465 of file res_pktccops.c.
References ast_cli_register_multiple(), AST_LIST_LOCK, AST_LIST_UNLOCK, AST_MODULE_LOAD_DECLINE, cli_pktccops, load_pktccops_config(), and restart_pktc_thread().
01466 { 01467 int res; 01468 AST_LIST_LOCK(&cmts_list); 01469 res = load_pktccops_config(); 01470 AST_LIST_UNLOCK(&cmts_list); 01471 if (res == -1) { 01472 return AST_MODULE_LOAD_DECLINE; 01473 } 01474 ast_cli_register_multiple(cli_pktccops, sizeof(cli_pktccops) / sizeof(struct ast_cli_entry)); 01475 restart_pktc_thread(); 01476 return 0; 01477 }
static int load_pktccops_config | ( | void | ) | [static] |
Definition at line 1024 of file res_pktccops.c.
References ast_category_browse(), ast_config_load, ast_log(), ast_variable_browse(), config, f, LOG_WARNING, ast_variable::name, ast_variable::next, update(), and ast_variable::value.
Referenced by do_pktccops(), and load_module().
01025 { 01026 static char *cfg = "res_pktccops.conf"; 01027 struct ast_config *config; 01028 struct ast_variable *v; 01029 struct cops_cmts *cmts; 01030 struct cops_ippool *new_ippool; 01031 const char *host, *cat, *port; 01032 int update; 01033 int res = 0; 01034 uint16_t t1_temp, t7_temp, t8_temp; 01035 uint32_t keepalive_temp; 01036 unsigned int a,b,c,d,e,f,g,h; 01037 struct ast_flags config_flags = {0}; 01038 01039 if (!(config = ast_config_load(cfg, config_flags))) { 01040 ast_log(LOG_WARNING, "Unable to load config file res_pktccops.conf\n"); 01041 return -1; 01042 } 01043 for (cat = ast_category_browse(config, NULL); cat; cat = ast_category_browse(config, cat)) { 01044 if (!strcmp(cat, "general")) { 01045 for (v = ast_variable_browse(config, cat); v; v = v->next) { 01046 if (!strcasecmp(v->name, "t1")) { 01047 t1 = atoi(v->value); 01048 } else if (!strcasecmp(v->name, "t7")) { 01049 t7 = atoi(v->value); 01050 } else if (!strcasecmp(v->name, "t8")) { 01051 t8 = atoi(v->value); 01052 } else if (!strcasecmp(v->name, "keepalive")) { 01053 keepalive = atoi(v->value); 01054 } else if (!strcasecmp(v->name, "gateinfoperiod")) { 01055 gateinfoperiod = atoi(v->value); 01056 } else if (!strcasecmp(v->name, "gatetimeout")) { 01057 gatetimeout = atoi(v->value); 01058 } else { 01059 ast_log(LOG_WARNING, "Unkown option %s in general section of res_ptkccops.conf\n", v->name); 01060 } 01061 } 01062 } else { 01063 /* Defaults */ 01064 host = NULL; 01065 port = NULL; 01066 t1_temp = t1; 01067 t7_temp = t7; 01068 t8_temp = t8; 01069 keepalive_temp = keepalive; 01070 01071 for (v = ast_variable_browse(config, cat); v; v = v->next) { 01072 if (!strcasecmp(v->name, "host")) { 01073 host = v->value; 01074 } else if (!strcasecmp(v->name, "port")) { 01075 port = v->value; 01076 } else if (!strcasecmp(v->name, "t1")) { 01077 t1_temp = atoi(v->value); 01078 } else if (!strcasecmp(v->name, "t7")) { 01079 t7_temp = atoi(v->value); 01080 } else if (!strcasecmp(v->name, "t8")) { 01081 t8_temp = atoi(v->value); 01082 } else if (!strcasecmp(v->name, "keepalive")) { 01083 keepalive_temp = atoi(v->value); 01084 } else if (!strcasecmp(v->name, "pool")) { 01085 /* we weill parse it in 2nd round */ 01086 } else { 01087 ast_log(LOG_WARNING, "Unkown option %s in res_ptkccops.conf\n", v->name); 01088 } 01089 } 01090 01091 update = 0; 01092 AST_LIST_TRAVERSE(&cmts_list, cmts, list) { 01093 if (!strcmp(cmts->name, cat)) { 01094 update = 1; 01095 break; 01096 } 01097 01098 } 01099 if (!update) { 01100 cmts = ast_calloc(1, sizeof(*cmts)); 01101 if (!cmts) { 01102 res = -1; 01103 break; 01104 } 01105 AST_LIST_INSERT_HEAD(&cmts_list, cmts, list); 01106 } 01107 if (cat) { 01108 ast_copy_string(cmts->name, cat, sizeof(cmts->name)); 01109 } 01110 if (host) { 01111 ast_copy_string(cmts->host, host, sizeof(cmts->host)); 01112 } 01113 if (port) { 01114 ast_copy_string(cmts->port, port, sizeof(cmts->port)); 01115 } else { 01116 ast_copy_string(cmts->port, DEFAULT_COPS_PORT, sizeof(cmts->port)); 01117 } 01118 01119 cmts->t1 = t1_temp; 01120 cmts->t7 = t7_temp; 01121 cmts->t8 = t8_temp; 01122 cmts->keepalive = keepalive_temp; 01123 if (!update) { 01124 cmts->state = 0; 01125 cmts->sfd = -1; 01126 } 01127 cmts->need_delete = 0; 01128 for (v = ast_variable_browse(config, cat); v; v = v->next) { 01129 /* parse ipppol when we have cmts ptr */ 01130 if (!strcasecmp(v->name, "pool")) { 01131 if (sscanf(v->value, "%3u.%3u.%3u.%3u %3u.%3u.%3u.%3u", &a, &b, &c, &d, &e, &f, &g, &h) == 8) { 01132 new_ippool = ast_calloc(1, sizeof(*new_ippool)); 01133 if (!new_ippool) { 01134 res = -1; 01135 break; 01136 } 01137 new_ippool->start = a << 24 | b << 16 | c << 8 | d; 01138 new_ippool->stop = e << 24 | f << 16 | g << 8 | h; 01139 new_ippool->cmts = cmts; 01140 pktccops_add_ippool(new_ippool); 01141 } else { 01142 ast_log(LOG_WARNING, "Invalid ip pool format in res_pktccops.conf\n"); 01143 } 01144 } 01145 } 01146 } 01147 } 01148 ast_config_destroy(config); 01149 return res; 01150 }
static int pktccops_add_ippool | ( | struct cops_ippool * | ippool | ) | [static] |
Definition at line 1422 of file res_pktccops.c.
References AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_cli_entry::list, and LOG_WARNING.
01423 { 01424 if (ippool) { 01425 AST_LIST_LOCK(&ippool_list); 01426 AST_LIST_INSERT_HEAD(&ippool_list, ippool, list); 01427 AST_LIST_UNLOCK(&ippool_list); 01428 return 0; 01429 } else { 01430 ast_log(LOG_WARNING, "Attempted to register NULL ippool?\n"); 01431 return -1; 01432 } 01433 }
static char* pktccops_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1385 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.
01386 { 01387 switch (cmd) { 01388 case CLI_INIT: 01389 e->command = "pktccops set debug {on|off}"; 01390 e->usage = 01391 "Usage: pktccops set debug {on|off}\n" 01392 " Turn on/off debuging\n"; 01393 return NULL; 01394 case CLI_GENERATE: 01395 return NULL; 01396 } 01397 01398 if (a->argc != e->args) 01399 return CLI_SHOWUSAGE; 01400 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 01401 pktccopsdebug = 1; 01402 ast_cli(a->fd, "PktcCOPS Debugging Enabled\n"); 01403 } else if (!strncasecmp(a->argv[e->args - 1], "off", 2)) { 01404 pktccopsdebug = 0; 01405 ast_cli(a->fd, "PktcCOPS Debugging Disabled\n"); 01406 } else { 01407 return CLI_SHOWUSAGE; 01408 } 01409 return CLI_SUCCESS; 01410 01411 }
static char* pktccops_gatedel | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1268 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::list, cops_cmts::name, and ast_cli_entry::usage.
01269 { 01270 int found = 0; 01271 int trid; 01272 uint32_t gateid; 01273 struct cops_gate *gate; 01274 struct cops_cmts *cmts; 01275 01276 switch (cmd) { 01277 case CLI_INIT: 01278 e->command = "pktccops gatedel"; 01279 e->usage = 01280 "Usage: pktccops gatedel <cmts> <gateid>\n" 01281 " Send Gate-Del to cmts.\n"; 01282 return NULL; 01283 case CLI_GENERATE: 01284 return NULL; 01285 } 01286 01287 if (a->argc < 4) 01288 return CLI_SHOWUSAGE; 01289 01290 AST_LIST_LOCK(&cmts_list); 01291 AST_LIST_TRAVERSE(&cmts_list, cmts, list) { 01292 if (!strcmp(cmts->name, a->argv[2])) { 01293 ast_cli(a->fd, "Found cmts: %s\n", cmts->name); 01294 found = 1; 01295 break; 01296 } 01297 } 01298 AST_LIST_UNLOCK(&cmts_list); 01299 01300 if (!found) 01301 return CLI_SHOWUSAGE; 01302 01303 trid = cops_trid++; 01304 if (!sscanf(a->argv[3], "%x", &gateid)) { 01305 ast_cli(a->fd, "bad gate specification (%s)\n", a->argv[3]); 01306 return CLI_SHOWUSAGE; 01307 } 01308 01309 found = 0; 01310 AST_LIST_LOCK(&gate_list); 01311 AST_LIST_TRAVERSE(&gate_list, gate, list) { 01312 if (gate->gateid == gateid && gate->cmts == cmts) { 01313 found = 1; 01314 break; 01315 } 01316 } 01317 01318 if (!found) { 01319 ast_cli(a->fd, "gate not found: %s\n", a->argv[3]); 01320 return CLI_SHOWUSAGE; 01321 } 01322 01323 AST_LIST_UNLOCK(&gate_list); 01324 cops_gate_cmd(GATE_DEL, cmts, trid, 0, 0, 0, 0, 0, 0, gate); 01325 return CLI_SUCCESS; 01326 }
static char* pktccops_gateset | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1328 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::list, cops_cmts::name, and ast_cli_entry::usage.
01329 { 01330 int foundcmts = 0; 01331 int trid; 01332 unsigned int an,bn,cn,dn; 01333 uint32_t mta, ssip; 01334 struct cops_cmts *cmts; 01335 01336 switch (cmd) { 01337 case CLI_INIT: 01338 e->command = "pktccops gateset"; 01339 e->usage = 01340 "Usage: pktccops gateset <cmts> <mta> <acctcount> <bitrate> <packet size> <switch ip> <switch port>\n" 01341 " Send Gate-Set to cmts.\n"; 01342 return NULL; 01343 case CLI_GENERATE: 01344 return NULL; 01345 } 01346 01347 if (a->argc < 9) 01348 return CLI_SHOWUSAGE; 01349 01350 if (!strncmp(a->argv[2], "null", sizeof(a->argv[2]))) { 01351 cmts = NULL; 01352 } else { 01353 AST_LIST_LOCK(&cmts_list); 01354 AST_LIST_TRAVERSE(&cmts_list, cmts, list) { 01355 if (!strcmp(cmts->name, a->argv[2])) { 01356 ast_cli(a->fd, "Found cmts: %s\n", cmts->name); 01357 foundcmts = 1; 01358 break; 01359 } 01360 } 01361 AST_LIST_UNLOCK(&cmts_list); 01362 if (!foundcmts) { 01363 ast_cli(a->fd, "CMTS not found: %s\n", a->argv[2]); 01364 return CLI_SHOWUSAGE; 01365 } 01366 } 01367 01368 trid = cops_trid++; 01369 if (sscanf(a->argv[3], "%3u.%3u.%3u.%3u", &an, &bn, &cn, &dn) != 4) { 01370 ast_cli(a->fd, "MTA specification (%s) does not look like an ipaddr\n", a->argv[3]); 01371 return CLI_SHOWUSAGE; 01372 } 01373 mta = an << 24 | bn << 16 | cn << 8 | dn; 01374 01375 if (sscanf(a->argv[7], "%3u.%3u.%3u.%3u", &an, &bn, &cn, &dn) != 4) { 01376 ast_cli(a->fd, "SSIP specification (%s) does not look like an ipaddr\n", a->argv[7]); 01377 return CLI_SHOWUSAGE; 01378 } 01379 ssip = an << 24 | bn << 16 | cn << 8 | dn; 01380 01381 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); 01382 return CLI_SUCCESS; 01383 }
static char* pktccops_show_cmtses | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1152 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::list, cops_cmts::name, cops_cmts::port, cops_cmts::state, and ast_cli_entry::usage.
01153 { 01154 struct cops_cmts *cmts; 01155 char statedesc[16]; 01156 int katimer; 01157 01158 switch(cmd) { 01159 case CLI_INIT: 01160 e->command = "pktccops show cmtses"; 01161 e->usage = 01162 "Usage: pktccops show cmtses\n" 01163 " List PacketCable COPS CMTSes.\n"; 01164 01165 return NULL; 01166 case CLI_GENERATE: 01167 return NULL; 01168 } 01169 01170 ast_cli(a->fd, "%-16s %-24s %-12s %7s\n", "Name ", "Host ", "Status ", "KA timer "); 01171 ast_cli(a->fd, "%-16s %-24s %-12s %7s\n", "------------", "--------------------", "----------", "-----------"); 01172 AST_LIST_LOCK(&cmts_list); 01173 AST_LIST_TRAVERSE(&cmts_list, cmts, list) { 01174 katimer = -1; 01175 if (cmts->state == 2) { 01176 ast_copy_string(statedesc, "Connected", sizeof(statedesc)); 01177 katimer = (int) (time(NULL) - cmts->katimer); 01178 } else if (cmts->state == 1) { 01179 ast_copy_string(statedesc, "Connecting", sizeof(statedesc)); 01180 } else { 01181 ast_copy_string(statedesc, "N/A", sizeof(statedesc)); 01182 } 01183 ast_cli(a->fd, "%-16s %-15s:%-8s %-12s %-7d\n", cmts->name, cmts->host, cmts->port, statedesc, katimer); 01184 } 01185 AST_LIST_UNLOCK(&cmts_list); 01186 return CLI_SUCCESS; 01187 }
static char* pktccops_show_gates | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1189 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.
01190 { 01191 struct cops_gate *gate; 01192 char state_desc[16]; 01193 01194 switch(cmd) { 01195 case CLI_INIT: 01196 e->command = "pktccops show gates"; 01197 e->usage = 01198 "Usage: pktccops show gates\n" 01199 " List PacketCable COPS GATEs.\n"; 01200 01201 return NULL; 01202 case CLI_GENERATE: 01203 return NULL; 01204 } 01205 01206 ast_cli(a->fd, "%-16s %-12s %-12s %-10s %-10s %-10s\n" ,"CMTS", "Gate-Id","MTA", "Status", "AllocTime", "CheckTime"); 01207 ast_cli(a->fd, "%-16s %-12s %-12s %-10s %-10s %-10s\n" ,"--------------" ,"----------", "----------", "--------", "--------", "--------\n"); 01208 AST_LIST_LOCK(&cmts_list); 01209 AST_LIST_LOCK(&gate_list); 01210 AST_LIST_TRAVERSE(&gate_list, gate, list) { 01211 if (gate->state == GATE_ALLOC_FAILED) { 01212 ast_copy_string(state_desc, "Failed", sizeof(state_desc)); 01213 } else if (gate->state == GATE_ALLOC_PROGRESS) { 01214 ast_copy_string(state_desc, "In Progress", sizeof(state_desc)); 01215 } else if (gate->state == GATE_ALLOCATED) { 01216 ast_copy_string(state_desc, "Allocated", sizeof(state_desc)); 01217 } else if (gate->state == GATE_CLOSED) { 01218 ast_copy_string(state_desc, "Closed", sizeof(state_desc)); 01219 } else if (gate->state == GATE_CLOSED_ERR) { 01220 ast_copy_string(state_desc, "ClosedErr", sizeof(state_desc)); 01221 } else if (gate->state == GATE_OPEN) { 01222 ast_copy_string(state_desc, "Open", sizeof(state_desc)); 01223 } else if (gate->state == GATE_DELETED) { 01224 ast_copy_string(state_desc, "Deleted", sizeof(state_desc)); 01225 } else { 01226 ast_copy_string(state_desc, "N/A", sizeof(state_desc)); 01227 } 01228 01229 ast_cli(a->fd, "%-16s 0x%.8x 0x%08x %-10s %10i %10i %u\n", (gate->cmts) ? gate->cmts->name : "null" , gate->gateid, gate->mta, 01230 state_desc, (int) (time(NULL) - gate->allocated), (gate->checked) ? (int) (time(NULL) - gate->checked) : 0, (unsigned int) gate->in_transaction); 01231 } 01232 AST_LIST_UNLOCK(&cmts_list); 01233 AST_LIST_UNLOCK(&gate_list); 01234 return CLI_SUCCESS; 01235 }
static char* pktccops_show_pools | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1237 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_ippool::list, cops_cmts::name, cops_ippool::start, cops_ippool::stop, stop, and ast_cli_entry::usage.
01238 { 01239 struct cops_ippool *ippool; 01240 char start[32]; 01241 char stop[32]; 01242 01243 switch(cmd) { 01244 case CLI_INIT: 01245 e->command = "pktccops show pools"; 01246 e->usage = 01247 "Usage: pktccops show pools\n" 01248 " List PacketCable COPS ip pools of MTAs.\n"; 01249 01250 return NULL; 01251 case CLI_GENERATE: 01252 return NULL; 01253 } 01254 01255 ast_cli(a->fd, "%-16s %-18s %-7s\n", "Start ", "Stop ", "CMTS "); 01256 ast_cli(a->fd, "%-16s %-18s %-7s\n", "----------", "----------", "--------"); 01257 AST_LIST_LOCK(&ippool_list); 01258 AST_LIST_TRAVERSE(&ippool_list, ippool, list) { 01259 snprintf(start, sizeof(start), "%3u.%3u.%3u.%3u", ippool->start >> 24, (ippool->start >> 16) & 0x000000ff, (ippool->start >> 8) & 0x000000ff, ippool->start & 0x000000ff); 01260 01261 snprintf(stop, sizeof(stop), "%3u.%3u.%3u.%3u", ippool->stop >> 24, (ippool->stop >> 16) & 0x000000ff, (ippool->stop >> 8) & 0x000000ff, ippool->stop & 0x000000ff); 01262 ast_cli(a->fd, "%-16s %-18s %-16s\n", start, stop, ippool->cmts->name); 01263 } 01264 AST_LIST_UNLOCK(&ippool_list); 01265 return CLI_SUCCESS; 01266 }
static void pktccops_unregister_cmtses | ( | void | ) | [static] |
Definition at line 1435 of file res_pktccops.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, cops_gate::cmts, free, and cops_cmts::sfd.
Referenced by unload_module().
01436 { 01437 struct cops_cmts *cmts; 01438 struct cops_gate *gate; 01439 AST_LIST_LOCK(&cmts_list); 01440 while ((cmts = AST_LIST_REMOVE_HEAD(&cmts_list, list))) { 01441 if (cmts->sfd > 0) { 01442 close(cmts->sfd); 01443 } 01444 free(cmts); 01445 } 01446 AST_LIST_UNLOCK(&cmts_list); 01447 01448 AST_LIST_LOCK(&gate_list); 01449 while ((gate = AST_LIST_REMOVE_HEAD(&gate_list, list))) { 01450 free(gate); 01451 } 01452 AST_LIST_UNLOCK(&gate_list); 01453 }
static void pktccops_unregister_ippools | ( | void | ) | [static] |
Definition at line 1455 of file res_pktccops.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free, and cops_ippool::list.
Referenced by do_pktccops(), and unload_module().
01456 { 01457 struct cops_ippool *ippool; 01458 AST_LIST_LOCK(&ippool_list); 01459 while ((ippool = AST_LIST_REMOVE_HEAD(&ippool_list, list))) { 01460 free(ippool); 01461 } 01462 AST_LIST_UNLOCK(&ippool_list); 01463 }
static int reload_module | ( | void | ) | [static] |
Definition at line 1501 of file res_pktccops.c.
References ast_log(), LOG_NOTICE, and pktcreload.
01502 { 01503 /* Prohibit unloading */ 01504 if (pktcreload) { 01505 ast_log(LOG_NOTICE, "Previous reload in progress, please wait!\n"); 01506 return -1; 01507 } 01508 pktcreload = 1; 01509 return 0; 01510 }
static int restart_pktc_thread | ( | void | ) | [static] |
Definition at line 995 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().
00996 { 00997 if (pktccops_thread == AST_PTHREADT_STOP) { 00998 return 0; 00999 } 01000 if (ast_mutex_lock(&pktccops_lock)) { 01001 ast_log(LOG_WARNING, "Unable to lock pktccops\n"); 01002 return -1; 01003 } 01004 if (pktccops_thread == pthread_self()) { 01005 ast_mutex_unlock(&pktccops_lock); 01006 ast_log(LOG_WARNING, "Cannot kill myself\n"); 01007 return -1; 01008 } 01009 if (pktccops_thread != AST_PTHREADT_NULL) { 01010 /* Wake up the thread */ 01011 pthread_kill(pktccops_thread, SIGURG); 01012 } else { 01013 /* Start a new monitor */ 01014 if (ast_pthread_create_background(&pktccops_thread, NULL, do_pktccops, NULL) < 0) { 01015 ast_mutex_unlock(&pktccops_lock); 01016 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 01017 return -1; 01018 } 01019 } 01020 ast_mutex_unlock(&pktccops_lock); 01021 return 0; 01022 }
static int unload_module | ( | void | ) | [static] |
Definition at line 1479 of file res_pktccops.c.
References ast_cli_unregister_multiple(), ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_PTHREADT_STOP, cli_pktccops, LOG_ERROR, pktccops_lock, pktccops_unregister_cmtses(), and pktccops_unregister_ippools().
01480 { 01481 if (!ast_mutex_lock(&pktccops_lock)) { 01482 if ((pktccops_thread != AST_PTHREADT_NULL) && (pktccops_thread != AST_PTHREADT_STOP)) { 01483 pthread_cancel(pktccops_thread); 01484 pthread_kill(pktccops_thread, SIGURG); 01485 pthread_join(pktccops_thread, NULL); 01486 } 01487 pktccops_thread = AST_PTHREADT_STOP; 01488 ast_mutex_unlock(&pktccops_lock); 01489 } else { 01490 ast_log(LOG_ERROR, "Unable to lock the pktccops_thread\n"); 01491 return -1; 01492 } 01493 01494 ast_cli_unregister_multiple(cli_pktccops, sizeof(cli_pktccops) / sizeof(struct ast_cli_entry)); 01495 pktccops_unregister_cmtses(); 01496 pktccops_unregister_ippools(); 01497 pktccops_thread = AST_PTHREADT_NULL; 01498 return 0; 01499 }
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 1516 of file res_pktccops.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1516 of file res_pktccops.c.
struct ast_cli_entry cli_pktccops[] [static] |
uint16_t cops_trid = 0 [static] |
Definition at line 92 of file res_pktccops.c.
int gateinfoperiod = 60 [static] |
int gatetimeout = 150 [static] |
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] |
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 AST_TEST_DEFINE(), ast_udptl_bridge(), create_match_char_tree(), dahdi_bridge(), is_prefix(), and remote_bridge_loop().
uint16_t t7 = 200 [static] |
uint16_t t8 = 300 [static] |
Definition at line 161 of file res_pktccops.c.