#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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .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 63 of file res_pktccops.c.
#define COPS_HEADER_SIZE 8 |
Definition at line 68 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 69 of file res_pktccops.c.
Referenced by cops_gate_cmd(), cops_getmsg(), and do_pktccops().
#define DEFAULT_COPS_PORT "2126" |
Definition at line 66 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 694 of file res_pktccops.c.
Referenced by do_pktccops().
#define PKTCCOPS_SCOMMAND_GATE_ALLOC 1 |
Definition at line 74 of file res_pktccops.c.
#define PKTCCOPS_SCOMMAND_GATE_ALLOC_ACK 2 |
Definition at line 75 of file res_pktccops.c.
#define PKTCCOPS_SCOMMAND_GATE_ALLOC_ERR 3 |
Definition at line 76 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 85 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 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 | |||
) |
Definition at line 469 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().
00474 { 00475 while (pktcreload) { 00476 sched_yield(); 00477 } 00478 00479 if (cmd == GATE_SET_HAVE_GATEID && gate) { 00480 ast_debug(3, "------- gate modify gateid 0x%x ssip: 0x%x\n", gate->gateid, ssip); 00481 /* TODO implement it */ 00482 ast_log(LOG_WARNING, "Modify GateID not implemented\n"); 00483 } 00484 00485 if ((gate = cops_gate_cmd(cmd, NULL, cops_trid++, mta, actcount, bitrate, psize, ssip, ssport, gate))) { 00486 ast_debug(3, "COPS: Allocating gate for mta: 0x%x\n", mta); 00487 gate->got_dq_gi = got_dq_gi; 00488 gate->gate_remove = gate_remove; 00489 return(gate); 00490 } else { 00491 ast_debug(3, "COPS: Couldn't allocate gate for mta: 0x%x\n", mta); 00492 return NULL; 00493 } 00494 }
static int cops_connect | ( | char * | host, | |
char * | port | |||
) | [static] |
Definition at line 650 of file res_pktccops.c.
References ast_debug, ast_log(), and LOG_WARNING.
Referenced by do_pktccops().
00651 { 00652 int s, sfd = -1, flags; 00653 struct addrinfo hints; 00654 struct addrinfo *rp; 00655 struct addrinfo *result; 00656 #ifdef HAVE_SO_NOSIGPIPE 00657 int trueval = 1; 00658 #endif 00659 00660 memset(&hints, 0, sizeof(struct addrinfo)); 00661 00662 hints.ai_family = AF_UNSPEC; 00663 hints.ai_socktype = SOCK_STREAM; 00664 hints.ai_flags = 0; 00665 hints.ai_protocol = 0; 00666 00667 s = getaddrinfo(host, port, &hints, &result); 00668 if (s != 0) { 00669 ast_log(LOG_WARNING, "COPS: getaddrinfo: %s\n", gai_strerror(s)); 00670 return -1; 00671 } 00672 00673 for (rp = result; rp != NULL; rp = rp->ai_next) { 00674 sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); 00675 if (sfd == -1) { 00676 ast_log(LOG_WARNING, "Failed socket\n"); 00677 } 00678 flags = fcntl(sfd, F_GETFL); 00679 fcntl(sfd, F_SETFL, flags | O_NONBLOCK); 00680 #ifdef HAVE_SO_NOSIGPIPE 00681 setsockopt(sfd, SOL_SOCKET, SO_NOSIGPIPE, &trueval, sizeof(trueval)); 00682 #endif 00683 connect(sfd, rp->ai_addr, rp->ai_addrlen); 00684 if (sfd == -1) { 00685 ast_log(LOG_WARNING, "Failed connect\n"); 00686 } 00687 } 00688 freeaddrinfo(result); 00689 00690 ast_debug(3, "Connecting to cmts: %s:%s\n", host, port); 00691 return(sfd); 00692 }
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 222 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().
00225 { 00226 struct gatespec gs; 00227 int offset = 0; 00228 00229 ast_debug(3, "CMD: %d\n", cmd); 00230 00231 /* Transaction Identifier 8 octets */ 00232 *(p + offset++) = 0; 00233 *(p + offset++) = 8; /* length */ 00234 *(p + offset++) = 1; /* snum */ 00235 *(p + offset++) = 1; /* stype */ 00236 *((uint16_t *) (p + offset)) = htons(trid); 00237 offset += 2; 00238 *(p + offset++) = 0; 00239 *(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 */ 00240 00241 /*Subscriper Identifier 8 octets */ 00242 *(p + offset++) = 0; 00243 *(p + offset++) = 8; /* length */ 00244 *(p + offset++) = 2; /* snum */ 00245 *(p + offset++) = 1; /* stype */ 00246 *((uint32_t *) (p + offset)) = htonl(mtahost); 00247 offset += 4; 00248 00249 if (cmd == GATE_INFO || cmd == GATE_SET_HAVE_GATEID || cmd == GATE_DEL) { 00250 /* Gate ID 8 Octets */ 00251 *(p + offset++) = 0; 00252 *(p + offset++) = 8; /* length */ 00253 *(p + offset++) = 3; /* snum */ 00254 *(p + offset++) = 1; /* stype */ 00255 *((uint32_t *) (p + offset)) = htonl(gateid); 00256 offset += 4; 00257 if (cmd == GATE_INFO || cmd == GATE_DEL) { 00258 return offset; 00259 } 00260 00261 } 00262 00263 /* Activity Count 8 octets */ 00264 *(p + offset++) = 0; 00265 *(p + offset++) = 8; /* length */ 00266 *(p + offset++) = 4; /* snum */ 00267 *(p + offset++) = 1; /* stype */ 00268 *((uint32_t *) (p + offset)) = htonl(actcount); 00269 offset += 4; 00270 00271 00272 /* Gate Spec 2*60 Octets */ 00273 gs.direction = 0; /* DS */ 00274 gs.protocolid = 17; /* UDP */ 00275 gs.flags = 0; 00276 gs.sessionclass = 1; 00277 gs.srcip = htonl(ssip); 00278 gs.dstip = htonl(mtahost); 00279 gs.srcp = htons(ssport); 00280 gs.dstp = 0; 00281 /* gs.diffserv = 0xa0;*/ 00282 gs.diffserv = 0; 00283 gs.t1 = htons(cmts->t1); 00284 gs.t7 = htons(cmts->t7); 00285 gs.t8 = htons(cmts->t8); 00286 gs.r = ftoieeef(rate); 00287 gs.b = ftoieeef(psizegateid); 00288 gs.p = ftoieeef(rate); 00289 gs.m = htonl((uint32_t) psizegateid); 00290 gs.mm = htonl((uint32_t) psizegateid); 00291 gs.rate = ftoieeef(rate); 00292 gs.s = htonl(800); 00293 00294 00295 *(p + offset) = 0; 00296 offset++; 00297 *(p + offset) = 60; /* length */ 00298 offset++; 00299 *(p + offset) = 5; /* snum */ 00300 offset++; 00301 *(p + offset) = 1; /* stype */ 00302 offset++; 00303 offset += cops_constructgatespec(&gs, p + offset); 00304 00305 00306 gs.direction = 1; /* US */ 00307 gs.srcip = htonl(mtahost); 00308 gs.dstip = htonl(ssip); 00309 gs.srcp = 0; 00310 gs.dstp = htons(ssport); 00311 *(p + offset) = 0; 00312 offset++; 00313 *(p + offset) = 60; /* length */ 00314 offset++; 00315 *(p + offset) = 5; /* snum */ 00316 offset++; 00317 *(p + offset) = 1; /* stype */ 00318 offset++; 00319 offset += cops_constructgatespec(&gs, p + offset); 00320 00321 return(offset); 00322 }
static uint16_t cops_constructgatespec | ( | struct gatespec * | gs, | |
char * | res | |||
) | [static] |
Definition at line 183 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().
00184 { 00185 if (res == NULL) { 00186 return 0; 00187 } 00188 00189 *res = (char) gs->direction; 00190 *(res + 1) = (char) gs->protocolid; 00191 *(res + 2) = (char) gs->flags; 00192 *(res + 3) = (char) gs->sessionclass; 00193 00194 *((uint32_t *) (res + 4)) = gs->srcip; 00195 *((uint32_t *) (res + 8)) = gs->dstip; 00196 00197 *((uint16_t *) (res + 12)) = gs->srcp; 00198 *((uint16_t *) (res + 14)) = gs->dstp; 00199 00200 *(res + 16) = (char) gs->diffserv; 00201 *(res + 17) = 0; /* reserved */ 00202 *(res + 18) = 0; /* reserved */ 00203 *(res + 19) = 0; /* reserved */ 00204 00205 *((uint16_t *) (res + 20)) = gs->t1; 00206 *(res + 22) = 0; /* reserved */ 00207 *(res + 23) = 0; /* reserved */ 00208 00209 *((uint16_t *) (res + 24)) = gs->t7; 00210 *((uint16_t *) (res + 26)) = gs->t8; 00211 00212 *((uint32_t *) (res + 28)) = gs->r; 00213 *((uint32_t *) (res + 32)) = gs->b; 00214 *((uint32_t *) (res + 36)) = gs->p; 00215 *((uint32_t *) (res + 40)) = gs->m; 00216 *((uint32_t *) (res + 44)) = gs->mm; 00217 *((uint32_t *) (res + 48)) = gs->rate; 00218 *((uint32_t *) (res + 52)) = gs->s; 00219 return 56; /* length */ 00220 };
static void cops_freemsg | ( | struct copsmsg * | p | ) | [static] |
Definition at line 454 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().
00455 { 00456 struct pktcobj *pnext; 00457 free(p->msg); 00458 p->msg = NULL; 00459 while (p->object != NULL) { 00460 pnext = p->object->next; 00461 ast_free(p->object->contents); 00462 p->object->contents = NULL; 00463 ast_free(p->object); 00464 p->object = pnext; 00465 } 00466 p->object = NULL; 00467 }
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 496 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().
00499 { 00500 struct copsmsg *gateset; 00501 struct cops_gate *new; 00502 struct cops_ippool *ippool; 00503 00504 if (cmd == GATE_DEL) { 00505 if (gate == NULL) { 00506 return NULL; 00507 } else { 00508 cmts = gate->cmts; 00509 } 00510 } 00511 00512 if (!cmts) { 00513 AST_LIST_LOCK(&ippool_list); 00514 AST_LIST_TRAVERSE(&ippool_list, ippool, list) { 00515 if (mta >= ippool->start && mta <= ippool->stop) { 00516 cmts = ippool->cmts; 00517 break; 00518 } 00519 } 00520 AST_LIST_UNLOCK(&ippool_list); 00521 if (!cmts) { 00522 ast_log(LOG_WARNING, "COPS: couldn't find cmts for mta: 0x%x\n", mta); 00523 return NULL; 00524 } 00525 if (cmts->sfd < 0) { 00526 ast_log(LOG_WARNING, "CMTS: %s not connected\n", cmts->name); 00527 return NULL; 00528 } 00529 } 00530 00531 if (cmd == GATE_SET) { 00532 new = ast_calloc(1, sizeof(*new)); 00533 new->gateid = 0; 00534 new->trid = trid; 00535 new->mta = mta; 00536 new->state = GATE_ALLOC_PROGRESS; 00537 new->checked = time(NULL); 00538 new->allocated = time(NULL); 00539 new->cmts = cmts; 00540 new->got_dq_gi = NULL; 00541 new->gate_remove = NULL; 00542 new->gate_open = NULL; 00543 new->tech_pvt = NULL; 00544 new->deltimer = 0; 00545 AST_LIST_LOCK(&gate_list); 00546 AST_LIST_INSERT_HEAD(&gate_list, new, list); 00547 AST_LIST_UNLOCK(&gate_list); 00548 gate = new; 00549 } else { 00550 if (gate) { 00551 gate->trid = trid; 00552 } 00553 } 00554 00555 gate->in_transaction = time(NULL); 00556 00557 if (!(gateset = malloc(sizeof(struct copsmsg)))) { 00558 free(gateset); 00559 return NULL; 00560 } 00561 gateset->msg = NULL; 00562 gateset->verflag = 0x10; 00563 gateset->opcode = 2; /* Decision */ 00564 gateset->clienttype = 0x8008; /* =PacketCable */ 00565 00566 /* Handle object */ 00567 gateset->object = malloc(sizeof(struct pktcobj)); 00568 if (!gateset->object) { 00569 cops_freemsg(gateset); 00570 free(gateset); 00571 return NULL; 00572 } 00573 gateset->object->length = COPS_OBJECT_HEADER_SIZE + 4; 00574 gateset->object->cnum = 1; /* Handle */ 00575 gateset->object->ctype = 1; /* client */ 00576 if (!(gateset->object->contents = malloc(sizeof(uint32_t)))) { 00577 cops_freemsg(gateset); 00578 free(gateset); 00579 return NULL; 00580 } 00581 *((uint32_t *) gateset->object->contents) = htonl(cmts->handle); 00582 00583 /* Context Object */ 00584 if (!(gateset->object->next = malloc(sizeof(struct pktcobj)))) { 00585 cops_freemsg(gateset); 00586 free(gateset); 00587 return NULL; 00588 } 00589 gateset->object->next->length = COPS_OBJECT_HEADER_SIZE + 4; 00590 gateset->object->next->cnum = 2; /* Context */ 00591 gateset->object->next->ctype = 1; /* Context */ 00592 if (!(gateset->object->next->contents = malloc(sizeof(uint32_t)))) { 00593 cops_freemsg(gateset); 00594 free(gateset); 00595 return NULL; 00596 } 00597 *((uint32_t *) gateset->object->next->contents) = htonl(0x00080000); /* R-Type = 8 configuration request, M-Type = 0 */ 00598 00599 /* Decision Object: Flags */ 00600 if (!(gateset->object->next->next = malloc(sizeof(struct pktcobj)))) { 00601 cops_freemsg(gateset); 00602 free(gateset); 00603 return NULL; 00604 } 00605 gateset->object->next->next->length = COPS_OBJECT_HEADER_SIZE + 4; 00606 gateset->object->next->next->cnum = 6; /* Decision */ 00607 gateset->object->next->next->ctype = 1; /* Flags */ 00608 if (!(gateset->object->next->next->contents = malloc(sizeof(uint32_t)))) { 00609 cops_freemsg(gateset); 00610 free(gateset); 00611 return NULL; 00612 } 00613 *((uint32_t *) gateset->object->next->next->contents) = htonl(0x00010001); /* Install, Trigger Error */ 00614 00615 /* Decision Object: Data */ 00616 if (!(gateset->object->next->next->next = malloc(sizeof(struct pktcobj)))) { 00617 cops_freemsg(gateset); 00618 free(gateset); 00619 return NULL; 00620 } 00621 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); 00622 gateset->object->next->next->next->cnum = 6; /* Decision */ 00623 gateset->object->next->next->next->ctype = 4; /* Decision Data */ 00624 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)); 00625 if (!gateset->object->next->next->next->contents) { 00626 cops_freemsg(gateset); 00627 free(gateset); 00628 return NULL; 00629 } 00630 gateset->object->next->next->next->next = NULL; 00631 00632 gateset->length = COPS_HEADER_SIZE + gateset->object->length + gateset->object->next->length + gateset->object->next->next->length + gateset->object->next->next->next->length; 00633 00634 if ((cmd == GATE_INFO || cmd == GATE_SET_HAVE_GATEID || cmd == GATE_DEL) && gate) { 00635 ast_debug(1, "Construct gate with gateid: 0x%x\n", gate->gateid); 00636 cops_construct_gate(cmd, gateset->object->next->next->next->contents, trid, mta, actcount, bitrate, psize, ssip, ssport, gate->gateid, cmts); 00637 } else { 00638 ast_debug(1, "Construct new gate\n"); 00639 cops_construct_gate(cmd, gateset->object->next->next->next->contents, trid, mta, actcount, bitrate, psize, ssip, ssport, 0, cmts); 00640 } 00641 if (pktccopsdebug) { 00642 ast_debug(3, "send cmd\n"); 00643 } 00644 cops_sendmsg(cmts->sfd, gateset); 00645 cops_freemsg(gateset); 00646 free(gateset); 00647 return gate; 00648 }
static int cops_getmsg | ( | int | sfd, | |
struct copsmsg * | recmsg | |||
) | [static] |
Definition at line 324 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().
00325 { 00326 int len, lent; 00327 char buf[COPS_HEADER_SIZE]; 00328 struct pktcobj *pobject = NULL; 00329 uint16_t *ubuf = (uint16_t *) buf; 00330 recmsg->msg = NULL; 00331 recmsg->object = NULL; 00332 len = recv(sfd, buf, COPS_HEADER_SIZE, MSG_DONTWAIT); 00333 if (len < COPS_HEADER_SIZE) { 00334 return len; 00335 } 00336 recmsg->verflag = *buf; 00337 recmsg->opcode = *(buf + 1); 00338 recmsg->clienttype = ntohs(*((uint16_t *) (buf + 2))); 00339 recmsg->length = ntohl(*((uint32_t *) (buf + 4))); 00340 /* Eg KA msg*/ 00341 if (recmsg->clienttype != 0x8008 ) { 00342 if (!(recmsg->msg = malloc(recmsg->length - COPS_HEADER_SIZE))) { 00343 return -1; 00344 } 00345 lent = recv(sfd, recmsg->msg, recmsg->length - COPS_HEADER_SIZE, MSG_DONTWAIT); 00346 if (lent < recmsg->length - COPS_HEADER_SIZE) { 00347 return lent; 00348 } 00349 len += len; 00350 } else { 00351 /* PacketCable Objects */ 00352 while (len < recmsg->length) { 00353 if (len == COPS_HEADER_SIZE) { 00354 /* 1st round */ 00355 if (!(recmsg->object = malloc(sizeof(struct pktcobj)))) { 00356 return -1; 00357 } 00358 pobject = recmsg->object; 00359 } else { 00360 if (!(pobject->next = malloc(sizeof(struct pktcobj)))) { 00361 return -1; 00362 } 00363 pobject = pobject->next; 00364 } 00365 pobject->next = NULL; 00366 lent = recv(sfd, buf, COPS_OBJECT_HEADER_SIZE, MSG_DONTWAIT); 00367 if (lent < COPS_OBJECT_HEADER_SIZE) { 00368 ast_debug(3, "Too short object header len: %i\n", lent); 00369 return lent; 00370 } 00371 len += lent; 00372 pobject->length = ntohs(*ubuf); 00373 pobject->cnum = *(buf + 2); 00374 pobject->ctype = *(buf + 3); 00375 if (!(pobject->contents = malloc(pobject->length - COPS_OBJECT_HEADER_SIZE))) { 00376 return -1; 00377 } 00378 lent = recv(sfd, pobject->contents, pobject->length - COPS_OBJECT_HEADER_SIZE, MSG_DONTWAIT); 00379 if (lent < pobject->length - COPS_OBJECT_HEADER_SIZE) { 00380 ast_debug(3, "Too short object content len: %i\n", lent); 00381 return lent; 00382 } 00383 len += lent; 00384 } 00385 } 00386 return len; 00387 }
static int cops_sendmsg | ( | int | sfd, | |
struct copsmsg * | sendmsg | |||
) | [static] |
Definition at line 389 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().
00390 { 00391 char *buf; 00392 int bufpos; 00393 struct pktcobj *pobject; 00394 00395 if (sfd < 0) { 00396 return -1; 00397 } 00398 00399 ast_debug(3, "COPS: sending opcode: %i len: %i\n", sendmsg->opcode, sendmsg->length); 00400 if (sendmsg->length < COPS_HEADER_SIZE) { 00401 ast_log(LOG_WARNING, "COPS: invalid msg size!!!\n"); 00402 return -1; 00403 } 00404 if (!(buf = malloc((size_t) sendmsg->length))) { 00405 return -1; 00406 } 00407 *buf = sendmsg->verflag ; 00408 *(buf + 1) = sendmsg->opcode; 00409 *((uint16_t *)(buf + 2)) = htons(sendmsg->clienttype); 00410 *((uint32_t *)(buf + 4)) = htonl(sendmsg->length); 00411 00412 if (sendmsg->msg != NULL) { 00413 memcpy(buf + COPS_HEADER_SIZE, sendmsg->msg, sendmsg->length - COPS_HEADER_SIZE); 00414 } else if (sendmsg->object != NULL) { 00415 bufpos = 8; 00416 pobject = sendmsg->object; 00417 while(pobject != NULL) { 00418 ast_debug(3, "COPS: Sending Object : cnum: %i ctype %i len: %i\n", pobject->cnum, pobject->ctype, pobject->length); 00419 if (sendmsg->length < bufpos + pobject->length) { 00420 ast_log(LOG_WARNING, "COPS: Invalid msg size len: %i objectlen: %i\n", sendmsg->length, pobject->length); 00421 free(buf); 00422 return -1; 00423 } 00424 *(uint16_t *) (buf + bufpos) = htons(pobject->length); 00425 *(buf + bufpos + 2) = pobject->cnum; 00426 *(buf + bufpos + 3) = pobject->ctype; 00427 if (sendmsg->length < pobject->length + bufpos) { 00428 ast_log(LOG_WARNING, "COPS: Error sum of object len more the msg len %i < %i\n", sendmsg->length, pobject->length + bufpos); 00429 free(buf); 00430 return -1; 00431 } 00432 memcpy((buf + bufpos + 4), pobject->contents, pobject->length - 4); 00433 bufpos += pobject->length; 00434 pobject = pobject->next; 00435 } 00436 } 00437 00438 errno = 0; 00439 #ifdef HAVE_MSG_NOSIGNAL 00440 #define SENDFLAGS MSG_NOSIGNAL | MSG_DONTWAIT 00441 #else 00442 #define SENDFLAGS MSG_DONTWAIT 00443 #endif 00444 if (send(sfd, buf, sendmsg->length, SENDFLAGS) == -1) { 00445 ast_log(LOG_WARNING, "COPS: Send failed errno=%i\n", errno); 00446 free(buf); 00447 return -2; 00448 } 00449 #undef SENDFLAGS 00450 free(buf); 00451 return 0; 00452 }
static void* do_pktccops | ( | void * | data | ) | [static] |
Definition at line 701 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().
00702 { 00703 int res, nfds, len; 00704 struct copsmsg *recmsg, *sendmsg; 00705 struct copsmsg recmsgb, sendmsgb; 00706 struct pollfd *pfds = NULL, *tmp; 00707 struct pktcobj *pobject; 00708 struct cops_cmts *cmts; 00709 struct cops_gate *gate; 00710 char *sobjp; 00711 uint16_t snst, sobjlen, scommand, recvtrid, actcount, reason, subreason; 00712 uint32_t gateid, subscrid, pktcerror; 00713 time_t last_exec = 0; 00714 00715 recmsg = &recmsgb; 00716 sendmsg = &sendmsgb; 00717 00718 ast_debug(3, "COPS: thread started\n"); 00719 00720 for (;;) { 00721 ast_free(pfds); 00722 pfds = NULL; 00723 nfds = 0; 00724 AST_LIST_LOCK(&cmts_list); 00725 AST_LIST_TRAVERSE(&cmts_list, cmts, list) { 00726 if (last_exec != time(NULL)) { 00727 if (cmts->state == 2 && cmts->katimer + cmts->keepalive < time(NULL)) { 00728 ast_log(LOG_WARNING, "KA timer (%is) expired cmts: %s\n", cmts->keepalive, cmts->name); 00729 cmts->state = 0; 00730 cmts->katimer = -1; 00731 close(cmts->sfd); 00732 cmts->sfd = -1; 00733 } 00734 } 00735 if (cmts->sfd > 0) { 00736 if (!(tmp = ast_realloc(pfds, (nfds + 1) * sizeof(*pfds)))) { 00737 continue; 00738 } 00739 pfds = tmp; 00740 pfds[nfds].fd = cmts->sfd; 00741 pfds[nfds].events = POLLIN; 00742 pfds[nfds].revents = 0; 00743 nfds++; 00744 } else { 00745 cmts->sfd = cops_connect(cmts->host, cmts->port); 00746 if (cmts->sfd > 0) { 00747 cmts->state = 1; 00748 if (cmts->sfd > 0) { 00749 if (!(tmp = ast_realloc(pfds, (nfds + 1) * sizeof(*pfds)))) { 00750 continue; 00751 } 00752 pfds = tmp; 00753 pfds[nfds].fd = cmts->sfd; 00754 pfds[nfds].events = POLLIN; 00755 pfds[nfds].revents = 0; 00756 nfds++; 00757 } 00758 } 00759 } 00760 } 00761 AST_LIST_UNLOCK(&cmts_list); 00762 00763 if (last_exec != time(NULL)) { 00764 last_exec = time(NULL); 00765 AST_LIST_LOCK(&gate_list); 00766 AST_LIST_TRAVERSE_SAFE_BEGIN(&gate_list, gate, list) { 00767 if (gate) { 00768 if (gate->deltimer && gate->deltimer < time(NULL)) { 00769 gate->deltimer = time(NULL) + 5; 00770 gate->trid = cops_trid++; 00771 cops_gate_cmd(GATE_DEL, gate->cmts, gate->trid, 0, 0, 0, 0, 0, 0, gate); 00772 ast_debug(3, "COPS: requested Gate-Del: CMTS: %s gateid: 0x%x\n", (gate->cmts) ? gate->cmts->name : "null", gate->gateid); 00773 } 00774 if (time(NULL) - gate->checked > gatetimeout) { 00775 ast_debug(3, "COPS: remove from list GATE, CMTS: %s gateid: 0x%x\n", (gate->cmts) ? gate->cmts->name : "null", gate->gateid); 00776 gate->state = GATE_TIMEOUT; 00777 PKTCCOPS_DESTROY_CURRENT_GATE; 00778 } else if (time(NULL) - gate->checked > gateinfoperiod && (gate->state == GATE_ALLOCATED || gate->state == GATE_OPEN)) { 00779 if (gate->cmts && (!gate->in_transaction || ( gate->in_transaction + 5 ) < time(NULL))) { 00780 gate->trid = cops_trid++; 00781 ast_debug(3, "COPS: Gate-Info send to CMTS: %s gateid: 0x%x\n", gate->cmts->name, gate->gateid); 00782 cops_gate_cmd(GATE_INFO, gate->cmts, gate->trid, gate->mta, 0, 0, 0, 0, 0, gate); 00783 } 00784 } 00785 } 00786 } 00787 AST_LIST_TRAVERSE_SAFE_END; 00788 AST_LIST_UNLOCK(&gate_list); 00789 } 00790 00791 if (pktcreload == 2) { 00792 pktcreload = 0; 00793 } 00794 if ((res = ast_poll(pfds, nfds, 1000))) { 00795 AST_LIST_LOCK(&cmts_list); 00796 AST_LIST_TRAVERSE(&cmts_list, cmts, list) { 00797 int idx; 00798 if ((idx = ast_poll_fd_index(pfds, nfds, cmts->sfd)) > -1 && (pfds[idx].revents & POLLIN)) { 00799 len = cops_getmsg(cmts->sfd, recmsg); 00800 if (len > 0) { 00801 ast_debug(3, "COPS: got from %s:\n Header: versflag=0x%.2x opcode=%i clienttype=0x%.4x msglength=%i\n", 00802 cmts->name, recmsg->verflag, recmsg->opcode, recmsg->clienttype, recmsg->length); 00803 if (recmsg->object != NULL) { 00804 pobject = recmsg->object; 00805 while (pobject != NULL) { 00806 ast_debug(3, " OBJECT: length=%i cnum=%i ctype=%i\n", pobject->length, pobject->cnum, pobject->ctype); 00807 if (recmsg->opcode == 1 && pobject->cnum == 1 && pobject->ctype == 1 ) { 00808 cmts->handle = ntohl(*((uint32_t *) pobject->contents)); 00809 ast_debug(3, " REQ client handle: %i\n", cmts->handle); 00810 cmts->state = 2; 00811 cmts->katimer = time(NULL); 00812 } else if (pobject->cnum == 9 && pobject->ctype == 1) { 00813 sobjp = pobject->contents; 00814 subscrid = 0; 00815 recvtrid = 0; 00816 scommand = 0; 00817 pktcerror = 0; 00818 actcount = 0; 00819 gateid = 0; 00820 reason = 0; 00821 subreason = 0; 00822 while (sobjp < (pobject->contents + pobject->length - 4)) { 00823 sobjlen = ntohs(*((uint16_t *) sobjp)); 00824 snst = ntohs(*((uint16_t *) (sobjp + 2))); 00825 ast_debug(3, " S-Num S-type: 0x%.4x len: %i\n", snst, sobjlen); 00826 if (snst == 0x0101 ) { 00827 recvtrid = ntohs(*((uint16_t *) (sobjp + 4))); 00828 scommand = ntohs(*((uint16_t *) (sobjp + 6))); 00829 ast_debug(3, " Transaction Identifier command: %i trid %i\n", scommand, recvtrid); 00830 } else if (snst == 0x0201) { 00831 subscrid = ntohl(*((uint32_t *) (sobjp + 4))); 00832 ast_debug(3, " Subscriber ID: 0x%.8x\n", subscrid); 00833 } else if (snst == 0x0301) { 00834 gateid = ntohl(*((uint32_t *) (sobjp + 4))); 00835 ast_debug(3, " Gate ID: 0x%x 0x%.8x\n", gateid, gateid); 00836 } else if (snst == 0x0401) { 00837 actcount = ntohs(*((uint16_t *) (sobjp + 6))); 00838 ast_debug(3, " Activity Count: %i\n", actcount); 00839 } else if (snst == 0x0901) { 00840 pktcerror = ntohl(*((uint32_t *) (sobjp + 4))); 00841 ast_debug(3, " PKTC Error: 0x%.8x\n", pktcerror); 00842 } else if (snst == 0x0d01) { 00843 reason = ntohs(*((uint16_t *) (sobjp + 4))); 00844 subreason = ntohs(*((uint16_t *) (sobjp + 6))); 00845 ast_debug(3, " Reason: %u Subreason: %u\n", reason, subreason); 00846 } 00847 sobjp += sobjlen; 00848 if (!sobjlen) 00849 break; 00850 } 00851 if (scommand == PKTCCOPS_SCOMMAND_GATE_CLOSE || scommand == PKTCCOPS_SCOMMAND_GATE_OPEN) { 00852 AST_LIST_LOCK(&gate_list); 00853 AST_LIST_TRAVERSE_SAFE_BEGIN(&gate_list, gate, list) { 00854 if (gate->cmts == cmts && gate->gateid == gateid) { 00855 if (scommand == PKTCCOPS_SCOMMAND_GATE_CLOSE && gate->state != GATE_CLOSED && gate->state != GATE_CLOSED_ERR ) { 00856 ast_debug(3, "COPS Gate Close Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name); 00857 if (subreason) { 00858 gate->state = GATE_CLOSED_ERR; 00859 PKTCCOPS_DESTROY_CURRENT_GATE; 00860 } else { 00861 gate->state = GATE_CLOSED; 00862 PKTCCOPS_DESTROY_CURRENT_GATE; 00863 } 00864 break; 00865 } else if (scommand == PKTCCOPS_SCOMMAND_GATE_OPEN && gate->state == GATE_ALLOCATED) { 00866 ast_debug(3, "COPS Gate Open Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name); 00867 gate->state = GATE_OPEN; 00868 if (gate->gate_open) { 00869 ast_debug(3, "Calling GATE-OPEN callback function\n"); 00870 gate->gate_open(gate); 00871 gate->gate_open = NULL; 00872 } 00873 break; 00874 } 00875 } 00876 } 00877 AST_LIST_TRAVERSE_SAFE_END; 00878 AST_LIST_UNLOCK(&gate_list); 00879 } 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) { 00880 AST_LIST_LOCK(&gate_list); 00881 AST_LIST_TRAVERSE_SAFE_BEGIN(&gate_list, gate, list) { 00882 if (gate->cmts == cmts && gate->trid == recvtrid) { 00883 gate->gateid = gateid; 00884 gate->checked = time(NULL); 00885 if (scommand == PKTCCOPS_SCOMMAND_GATE_SET_ACK) { 00886 ast_debug(3, "COPS Gate Set Ack Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name); 00887 gate->state = GATE_ALLOCATED; 00888 if (gate->got_dq_gi) { 00889 gate->got_dq_gi(gate); 00890 gate->got_dq_gi = NULL; 00891 } 00892 } else if (scommand == PKTCCOPS_SCOMMAND_GATE_SET_ERR) { 00893 ast_debug(3, "COPS Gate Set Error TrId: %i ErrorCode: 0x%.8x CMTS: %s\n ", recvtrid, pktcerror, cmts->name); 00894 gate->state = GATE_ALLOC_FAILED; 00895 if (gate->got_dq_gi) { 00896 gate->got_dq_gi(gate); 00897 gate->got_dq_gi = NULL; 00898 } 00899 PKTCCOPS_DESTROY_CURRENT_GATE; 00900 } else if (scommand == PKTCCOPS_SCOMMAND_GATE_INFO_ACK) { 00901 ast_debug(3, "COPS Gate Info Ack Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name); 00902 } else if (scommand == PKTCCOPS_SCOMMAND_GATE_INFO_ERR) { 00903 ast_debug(3, "COPS Gate Info Error Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name); 00904 gate->state = GATE_ALLOC_FAILED; 00905 PKTCCOPS_DESTROY_CURRENT_GATE; 00906 } else if (scommand == PKTCCOPS_SCOMMAND_GATE_DELETE_ACK) { 00907 ast_debug(3, "COPS Gate Deleted Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name); 00908 gate->state = GATE_DELETED; 00909 PKTCCOPS_DESTROY_CURRENT_GATE; 00910 } 00911 gate->in_transaction = 0; 00912 break; 00913 } 00914 } 00915 AST_LIST_TRAVERSE_SAFE_END; 00916 AST_LIST_UNLOCK(&gate_list); 00917 } 00918 } 00919 pobject = pobject->next; 00920 } 00921 } 00922 00923 if (recmsg->opcode == 6 && recmsg->object && recmsg->object->cnum == 11 && recmsg->object->ctype == 1) { 00924 ast_debug(3, "COPS: Client open %s\n", cmts->name); 00925 sendmsg->msg = NULL; 00926 sendmsg->verflag = 0x10; 00927 sendmsg->opcode = 7; /* Client Accept */ 00928 sendmsg->clienttype = 0x8008; /* =PacketCable */ 00929 sendmsg->length = COPS_HEADER_SIZE + COPS_OBJECT_HEADER_SIZE + 4; 00930 sendmsg->object = malloc(sizeof(struct pktcobj)); 00931 sendmsg->object->length = 4 + COPS_OBJECT_HEADER_SIZE; 00932 sendmsg->object->cnum = 10; /* keppalive timer*/ 00933 sendmsg->object->ctype = 1; 00934 sendmsg->object->contents = malloc(sizeof(uint32_t)); 00935 *((uint32_t *) sendmsg->object->contents) = htonl(cmts->keepalive & 0x0000ffff); 00936 sendmsg->object->next = NULL; 00937 cops_sendmsg(cmts->sfd, sendmsg); 00938 cops_freemsg(sendmsg); 00939 } else if (recmsg->opcode == 9) { 00940 ast_debug(3, "COPS: Keepalive Request got echoing back %s\n", cmts->name); 00941 cops_sendmsg(cmts->sfd, recmsg); 00942 cmts->state = 2; 00943 cmts->katimer = time(NULL); 00944 } 00945 } 00946 if (len <= 0) { 00947 ast_debug(3, "COPS: lost connection to %s\n", cmts->name); 00948 close(cmts->sfd); 00949 cmts->sfd = -1; 00950 cmts->state = 0; 00951 } 00952 cops_freemsg(recmsg); 00953 } 00954 } 00955 AST_LIST_UNLOCK(&cmts_list); 00956 } 00957 if (pktcreload) { 00958 ast_debug(3, "Reloading pktccops...\n"); 00959 AST_LIST_LOCK(&gate_list); 00960 AST_LIST_LOCK(&cmts_list); 00961 pktccops_unregister_ippools(); 00962 AST_LIST_TRAVERSE(&cmts_list, cmts, list) { 00963 cmts->need_delete = 1; 00964 } 00965 load_pktccops_config(); 00966 AST_LIST_TRAVERSE_SAFE_BEGIN(&cmts_list, cmts, list) { 00967 if (cmts && cmts->need_delete) { 00968 AST_LIST_TRAVERSE(&gate_list, gate, list) { 00969 if (gate->cmts == cmts) { 00970 ast_debug(3, "Null gate %s\n", gate->cmts->name); 00971 gate->cmts = NULL; 00972 } 00973 gate->in_transaction = 0; 00974 } 00975 AST_LIST_UNLOCK(&gate_list); 00976 ast_debug(3, "removing cmts: %s\n", cmts->name); 00977 if (cmts->sfd > 0) { 00978 close(cmts->sfd); 00979 } 00980 AST_LIST_REMOVE_CURRENT(list); 00981 free(cmts); 00982 } 00983 } 00984 AST_LIST_TRAVERSE_SAFE_END; 00985 AST_LIST_UNLOCK(&cmts_list); 00986 AST_LIST_UNLOCK(&gate_list); 00987 pktcreload = 2; 00988 } 00989 pthread_testcancel(); 00990 } 00991 return NULL; 00992 }
static uint32_t ftoieeef | ( | float | n | ) | [static] |
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, cli_pktccops, 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 1023 of file res_pktccops.c.
References ast_category_browse(), ast_config_load, ast_log(), ast_variable_browse(), config, config_flags, f, LOG_WARNING, ast_variable::name, ast_variable::next, update(), and ast_variable::value.
Referenced by do_pktccops(), and load_module().
01024 { 01025 static char *cfg = "res_pktccops.conf"; 01026 struct ast_config *config; 01027 struct ast_variable *v; 01028 struct cops_cmts *cmts; 01029 struct cops_ippool *new_ippool; 01030 const char *host, *cat, *port; 01031 int sfd, update; 01032 int res = 0; 01033 uint16_t t1_temp, t7_temp, t8_temp; 01034 uint32_t keepalive_temp; 01035 unsigned int a,b,c,d,e,f,g,h; 01036 struct ast_flags config_flags = {0}; 01037 01038 if (!(config = ast_config_load(cfg, config_flags))) { 01039 ast_log(LOG_WARNING, "Unable to load config file res_pktccops.conf\n"); 01040 return -1; 01041 } 01042 for (cat = ast_category_browse(config, NULL); cat; cat = ast_category_browse(config, cat)) { 01043 if (!strcmp(cat, "general")) { 01044 for (v = ast_variable_browse(config, cat); v; v = v->next) { 01045 if (!strcasecmp(v->name, "t1")) { 01046 t1 = atoi(v->value); 01047 } else if (!strcasecmp(v->name, "t7")) { 01048 t7 = atoi(v->value); 01049 } else if (!strcasecmp(v->name, "t8")) { 01050 t8 = atoi(v->value); 01051 } else if (!strcasecmp(v->name, "keepalive")) { 01052 keepalive = atoi(v->value); 01053 } else if (!strcasecmp(v->name, "gateinfoperiod")) { 01054 gateinfoperiod = atoi(v->value); 01055 } else if (!strcasecmp(v->name, "gatetimeout")) { 01056 gatetimeout = atoi(v->value); 01057 } else { 01058 ast_log(LOG_WARNING, "Unkown option %s in general section of res_ptkccops.conf\n", v->name); 01059 } 01060 } 01061 } else { 01062 /* Defaults */ 01063 host = NULL; 01064 port = NULL; 01065 sfd = 0; 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 1423 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.
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 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, cops_gate::cmts, ast_cli_entry::command, cops_gate_cmd(), ast_cli_args::fd, GATE_SET, 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 struct cops_gate *gate; 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 (!strncmp(a->argv[2], "null", sizeof(a->argv[2]))) { 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 gate = 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 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 1436 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().
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, free, and cops_ippool::list.
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 994 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().
00995 { 00996 if (pktccops_thread == AST_PTHREADT_STOP) { 00997 return 0; 00998 } 00999 if (ast_mutex_lock(&pktccops_lock)) { 01000 ast_log(LOG_WARNING, "Unable to lock pktccops\n"); 01001 return -1; 01002 } 01003 if (pktccops_thread == pthread_self()) { 01004 ast_mutex_unlock(&pktccops_lock); 01005 ast_log(LOG_WARNING, "Cannot kill myself\n"); 01006 return -1; 01007 } 01008 if (pktccops_thread != AST_PTHREADT_NULL) { 01009 /* Wake up the thread */ 01010 pthread_kill(pktccops_thread, SIGURG); 01011 } else { 01012 /* Start a new monitor */ 01013 if (ast_pthread_create_background(&pktccops_thread, NULL, do_pktccops, NULL) < 0) { 01014 ast_mutex_unlock(&pktccops_lock); 01015 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 01016 return -1; 01017 } 01018 } 01019 ast_mutex_unlock(&pktccops_lock); 01020 return 0; 01021 }
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, cli_pktccops, 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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .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] |
uint16_t cops_trid = 0 [static] |
Definition at line 91 of file res_pktccops.c.
int gateinfoperiod = 60 [static] |
int gatetimeout = 150 [static] |
uint32_t keepalive = 60 [static] |
Definition at line 161 of file res_pktccops.c.
ast_mutex_t pktccops_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 89 of file res_pktccops.c.
Referenced by restart_pktc_thread(), and unload_module().
pthread_t pktccops_thread = AST_PTHREADT_NULL [static] |
Definition at line 90 of file res_pktccops.c.
int pktccopsdebug = 0 [static] |
int pktcreload = 0 [static] |
Definition at line 163 of file res_pktccops.c.
Referenced by ast_pktccops_gate_alloc(), do_pktccops(), and reload_module().
uint16_t t1 = 250 [static] |
Definition at line 158 of file res_pktccops.c.
Referenced by ast_udptl_bridge(), create_match_char_tree(), dahdi_bridge(), is_prefix(), and remote_bridge_loop().
uint16_t t7 = 200 [static] |
Definition at line 159 of file res_pktccops.c.
uint16_t t8 = 300 [static] |
Definition at line 160 of file res_pktccops.c.