#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 = "88eaa8f5c1bd988bedd71113385e0886" , .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 1518 of file res_pktccops.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 1518 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 1467 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().
01468 { 01469 int res; 01470 AST_LIST_LOCK(&cmts_list); 01471 res = load_pktccops_config(); 01472 AST_LIST_UNLOCK(&cmts_list); 01473 if (res == -1) { 01474 return AST_MODULE_LOAD_DECLINE; 01475 } 01476 ast_cli_register_multiple(cli_pktccops, sizeof(cli_pktccops) / sizeof(struct ast_cli_entry)); 01477 restart_pktc_thread(); 01478 return 0; 01479 }
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, config_flags, 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 sfd, 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 sfd = 0; 01067 t1_temp = t1; 01068 t7_temp = t7; 01069 t8_temp = t8; 01070 keepalive_temp = keepalive; 01071 01072 for (v = ast_variable_browse(config, cat); v; v = v->next) { 01073 if (!strcasecmp(v->name, "host")) { 01074 host = v->value; 01075 } else if (!strcasecmp(v->name, "port")) { 01076 port = v->value; 01077 } else if (!strcasecmp(v->name, "t1")) { 01078 t1_temp = atoi(v->value); 01079 } else if (!strcasecmp(v->name, "t7")) { 01080 t7_temp = atoi(v->value); 01081 } else if (!strcasecmp(v->name, "t8")) { 01082 t8_temp = atoi(v->value); 01083 } else if (!strcasecmp(v->name, "keepalive")) { 01084 keepalive_temp = atoi(v->value); 01085 } else if (!strcasecmp(v->name, "pool")) { 01086 /* we weill parse it in 2nd round */ 01087 } else { 01088 ast_log(LOG_WARNING, "Unkown option %s in res_ptkccops.conf\n", v->name); 01089 } 01090 } 01091 01092 update = 0; 01093 AST_LIST_TRAVERSE(&cmts_list, cmts, list) { 01094 if (!strcmp(cmts->name, cat)) { 01095 update = 1; 01096 break; 01097 } 01098 01099 } 01100 if (!update) { 01101 cmts = ast_calloc(1, sizeof(*cmts)); 01102 if (!cmts) { 01103 res = -1; 01104 break; 01105 } 01106 AST_LIST_INSERT_HEAD(&cmts_list, cmts, list); 01107 } 01108 if (cat) { 01109 ast_copy_string(cmts->name, cat, sizeof(cmts->name)); 01110 } 01111 if (host) { 01112 ast_copy_string(cmts->host, host, sizeof(cmts->host)); 01113 } 01114 if (port) { 01115 ast_copy_string(cmts->port, port, sizeof(cmts->port)); 01116 } else { 01117 ast_copy_string(cmts->port, DEFAULT_COPS_PORT, sizeof(cmts->port)); 01118 } 01119 01120 cmts->t1 = t1_temp; 01121 cmts->t7 = t7_temp; 01122 cmts->t8 = t8_temp; 01123 cmts->keepalive = keepalive_temp; 01124 if (!update) { 01125 cmts->state = 0; 01126 cmts->sfd = -1; 01127 } 01128 cmts->need_delete = 0; 01129 for (v = ast_variable_browse(config, cat); v; v = v->next) { 01130 /* parse ipppol when we have cmts ptr */ 01131 if (!strcasecmp(v->name, "pool")) { 01132 if (sscanf(v->value, "%3u.%3u.%3u.%3u %3u.%3u.%3u.%3u", &a, &b, &c, &d, &e, &f, &g, &h) == 8) { 01133 new_ippool = ast_calloc(1, sizeof(*new_ippool)); 01134 if (!new_ippool) { 01135 res = -1; 01136 break; 01137 } 01138 new_ippool->start = a << 24 | b << 16 | c << 8 | d; 01139 new_ippool->stop = e << 24 | f << 16 | g << 8 | h; 01140 new_ippool->cmts = cmts; 01141 pktccops_add_ippool(new_ippool); 01142 } else { 01143 ast_log(LOG_WARNING, "Invalid ip pool format in res_pktccops.conf\n"); 01144 } 01145 } 01146 } 01147 } 01148 } 01149 ast_config_destroy(config); 01150 return res; 01151 }
static int pktccops_add_ippool | ( | struct cops_ippool * | ippool | ) | [static] |
Definition at line 1424 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.
01425 { 01426 if (ippool) { 01427 AST_LIST_LOCK(&ippool_list); 01428 AST_LIST_INSERT_HEAD(&ippool_list, ippool, list); 01429 AST_LIST_UNLOCK(&ippool_list); 01430 return 0; 01431 } else { 01432 ast_log(LOG_WARNING, "Attempted to register NULL ippool?\n"); 01433 return -1; 01434 } 01435 }
static char* pktccops_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1387 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.
01388 { 01389 switch (cmd) { 01390 case CLI_INIT: 01391 e->command = "pktccops set debug {on|off}"; 01392 e->usage = 01393 "Usage: pktccops set debug {on|off}\n" 01394 " Turn on/off debuging\n"; 01395 return NULL; 01396 case CLI_GENERATE: 01397 return NULL; 01398 } 01399 01400 if (a->argc != e->args) 01401 return CLI_SHOWUSAGE; 01402 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 01403 pktccopsdebug = 1; 01404 ast_cli(a->fd, "PktcCOPS Debugging Enabled\n"); 01405 } else if (!strncasecmp(a->argv[e->args - 1], "off", 2)) { 01406 pktccopsdebug = 0; 01407 ast_cli(a->fd, "PktcCOPS Debugging Disabled\n"); 01408 } else { 01409 return CLI_SHOWUSAGE; 01410 } 01411 return CLI_SUCCESS; 01412 01413 }
static char* pktccops_gatedel | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1269 of file res_pktccops.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, cops_gate::cmts, ast_cli_entry::command, cops_gate_cmd(), ast_cli_args::fd, GATE_DEL, cops_gate::gateid, cops_cmts::list, cops_cmts::name, and ast_cli_entry::usage.
01270 { 01271 int found = 0; 01272 int trid; 01273 uint32_t gateid; 01274 struct cops_gate *gate; 01275 struct cops_cmts *cmts; 01276 01277 switch (cmd) { 01278 case CLI_INIT: 01279 e->command = "pktccops gatedel"; 01280 e->usage = 01281 "Usage: pktccops gatedel <cmts> <gateid>\n" 01282 " Send Gate-Del to cmts.\n"; 01283 return NULL; 01284 case CLI_GENERATE: 01285 return NULL; 01286 } 01287 01288 if (a->argc < 4) 01289 return CLI_SHOWUSAGE; 01290 01291 AST_LIST_LOCK(&cmts_list); 01292 AST_LIST_TRAVERSE(&cmts_list, cmts, list) { 01293 if (!strcmp(cmts->name, a->argv[2])) { 01294 ast_cli(a->fd, "Found cmts: %s\n", cmts->name); 01295 found = 1; 01296 break; 01297 } 01298 } 01299 AST_LIST_UNLOCK(&cmts_list); 01300 01301 if (!found) 01302 return CLI_SHOWUSAGE; 01303 01304 trid = cops_trid++; 01305 if (!sscanf(a->argv[3], "%x", &gateid)) { 01306 ast_cli(a->fd, "bad gate specification (%s)\n", a->argv[3]); 01307 return CLI_SHOWUSAGE; 01308 } 01309 01310 found = 0; 01311 AST_LIST_LOCK(&gate_list); 01312 AST_LIST_TRAVERSE(&gate_list, gate, list) { 01313 if (gate->gateid == gateid && gate->cmts == cmts) { 01314 found = 1; 01315 break; 01316 } 01317 } 01318 01319 if (!found) { 01320 ast_cli(a->fd, "gate not found: %s\n", a->argv[3]); 01321 return CLI_SHOWUSAGE; 01322 } 01323 01324 AST_LIST_UNLOCK(&gate_list); 01325 cops_gate_cmd(GATE_DEL, cmts, trid, 0, 0, 0, 0, 0, 0, gate); 01326 return CLI_SUCCESS; 01327 }
static char* pktccops_gateset | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1329 of file res_pktccops.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, cops_gate::cmts, ast_cli_entry::command, cops_gate_cmd(), ast_cli_args::fd, GATE_SET, cops_cmts::name, and ast_cli_entry::usage.
01330 { 01331 int foundcmts = 0; 01332 int trid; 01333 unsigned int an,bn,cn,dn; 01334 uint32_t mta, ssip; 01335 struct cops_cmts *cmts; 01336 struct cops_gate *gate; 01337 01338 switch (cmd) { 01339 case CLI_INIT: 01340 e->command = "pktccops gateset"; 01341 e->usage = 01342 "Usage: pktccops gateset <cmts> <mta> <acctcount> <bitrate> <packet size> <switch ip> <switch port>\n" 01343 " Send Gate-Set to cmts.\n"; 01344 return NULL; 01345 case CLI_GENERATE: 01346 return NULL; 01347 } 01348 01349 if (a->argc < 9) 01350 return CLI_SHOWUSAGE; 01351 01352 if (!strncmp(a->argv[2], "null", sizeof(a->argv[2]))) { 01353 cmts = NULL; 01354 } else { 01355 AST_LIST_LOCK(&cmts_list); 01356 AST_LIST_TRAVERSE(&cmts_list, cmts, list) { 01357 if (!strcmp(cmts->name, a->argv[2])) { 01358 ast_cli(a->fd, "Found cmts: %s\n", cmts->name); 01359 foundcmts = 1; 01360 break; 01361 } 01362 } 01363 AST_LIST_UNLOCK(&cmts_list); 01364 if (!foundcmts) { 01365 ast_cli(a->fd, "CMTS not found: %s\n", a->argv[2]); 01366 return CLI_SHOWUSAGE; 01367 } 01368 } 01369 01370 trid = cops_trid++; 01371 if (sscanf(a->argv[3], "%3u.%3u.%3u.%3u", &an, &bn, &cn, &dn) != 4) { 01372 ast_cli(a->fd, "MTA specification (%s) does not look like an ipaddr\n", a->argv[3]); 01373 return CLI_SHOWUSAGE; 01374 } 01375 mta = an << 24 | bn << 16 | cn << 8 | dn; 01376 01377 if (sscanf(a->argv[7], "%3u.%3u.%3u.%3u", &an, &bn, &cn, &dn) != 4) { 01378 ast_cli(a->fd, "SSIP specification (%s) does not look like an ipaddr\n", a->argv[7]); 01379 return CLI_SHOWUSAGE; 01380 } 01381 ssip = an << 24 | bn << 16 | cn << 8 | dn; 01382 01383 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); 01384 return CLI_SUCCESS; 01385 }
static char* pktccops_show_cmtses | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1153 of file res_pktccops.c.
References ast_cli(), ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, cops_cmts::host, cops_cmts::katimer, cops_cmts::list, cops_cmts::name, cops_cmts::port, cops_cmts::state, and ast_cli_entry::usage.
01154 { 01155 struct cops_cmts *cmts; 01156 char statedesc[16]; 01157 int katimer; 01158 01159 switch(cmd) { 01160 case CLI_INIT: 01161 e->command = "pktccops show cmtses"; 01162 e->usage = 01163 "Usage: pktccops show cmtses\n" 01164 " List PacketCable COPS CMTSes.\n"; 01165 01166 return NULL; 01167 case CLI_GENERATE: 01168 return NULL; 01169 } 01170 01171 ast_cli(a->fd, "%-16s %-24s %-12s %7s\n", "Name ", "Host ", "Status ", "KA timer "); 01172 ast_cli(a->fd, "%-16s %-24s %-12s %7s\n", "------------", "--------------------", "----------", "-----------"); 01173 AST_LIST_LOCK(&cmts_list); 01174 AST_LIST_TRAVERSE(&cmts_list, cmts, list) { 01175 katimer = -1; 01176 if (cmts->state == 2) { 01177 ast_copy_string(statedesc, "Connected", sizeof(statedesc)); 01178 katimer = (int) (time(NULL) - cmts->katimer); 01179 } else if (cmts->state == 1) { 01180 ast_copy_string(statedesc, "Connecting", sizeof(statedesc)); 01181 } else { 01182 ast_copy_string(statedesc, "N/A", sizeof(statedesc)); 01183 } 01184 ast_cli(a->fd, "%-16s %-15s:%-8s %-12s %-7d\n", cmts->name, cmts->host, cmts->port, statedesc, katimer); 01185 } 01186 AST_LIST_UNLOCK(&cmts_list); 01187 return CLI_SUCCESS; 01188 }
static char* pktccops_show_gates | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1190 of file res_pktccops.c.
References cops_gate::allocated, ast_cli(), ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, cops_gate::checked, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, cops_gate::cmts, ast_cli_entry::command, ast_cli_args::fd, GATE_ALLOC_FAILED, GATE_ALLOC_PROGRESS, GATE_ALLOCATED, GATE_CLOSED, GATE_CLOSED_ERR, GATE_DELETED, GATE_OPEN, cops_gate::gateid, cops_gate::in_transaction, cops_gate::mta, cops_cmts::name, cops_gate::state, and ast_cli_entry::usage.
01191 { 01192 struct cops_gate *gate; 01193 char state_desc[16]; 01194 01195 switch(cmd) { 01196 case CLI_INIT: 01197 e->command = "pktccops show gates"; 01198 e->usage = 01199 "Usage: pktccops show gates\n" 01200 " List PacketCable COPS GATEs.\n"; 01201 01202 return NULL; 01203 case CLI_GENERATE: 01204 return NULL; 01205 } 01206 01207 ast_cli(a->fd, "%-16s %-12s %-12s %-10s %-10s %-10s\n" ,"CMTS", "Gate-Id","MTA", "Status", "AllocTime", "CheckTime"); 01208 ast_cli(a->fd, "%-16s %-12s %-12s %-10s %-10s %-10s\n" ,"--------------" ,"----------", "----------", "--------", "--------", "--------\n"); 01209 AST_LIST_LOCK(&cmts_list); 01210 AST_LIST_LOCK(&gate_list); 01211 AST_LIST_TRAVERSE(&gate_list, gate, list) { 01212 if (gate->state == GATE_ALLOC_FAILED) { 01213 ast_copy_string(state_desc, "Failed", sizeof(state_desc)); 01214 } else if (gate->state == GATE_ALLOC_PROGRESS) { 01215 ast_copy_string(state_desc, "In Progress", sizeof(state_desc)); 01216 } else if (gate->state == GATE_ALLOCATED) { 01217 ast_copy_string(state_desc, "Allocated", sizeof(state_desc)); 01218 } else if (gate->state == GATE_CLOSED) { 01219 ast_copy_string(state_desc, "Closed", sizeof(state_desc)); 01220 } else if (gate->state == GATE_CLOSED_ERR) { 01221 ast_copy_string(state_desc, "ClosedErr", sizeof(state_desc)); 01222 } else if (gate->state == GATE_OPEN) { 01223 ast_copy_string(state_desc, "Open", sizeof(state_desc)); 01224 } else if (gate->state == GATE_DELETED) { 01225 ast_copy_string(state_desc, "Deleted", sizeof(state_desc)); 01226 } else { 01227 ast_copy_string(state_desc, "N/A", sizeof(state_desc)); 01228 } 01229 01230 ast_cli(a->fd, "%-16s 0x%.8x 0x%08x %-10s %10i %10i %u\n", (gate->cmts) ? gate->cmts->name : "null" , gate->gateid, gate->mta, 01231 state_desc, (int) (time(NULL) - gate->allocated), (gate->checked) ? (int) (time(NULL) - gate->checked) : 0, (unsigned int) gate->in_transaction); 01232 } 01233 AST_LIST_UNLOCK(&cmts_list); 01234 AST_LIST_UNLOCK(&gate_list); 01235 return CLI_SUCCESS; 01236 }
static char* pktccops_show_pools | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1238 of file res_pktccops.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, cops_ippool::cmts, ast_cli_entry::command, ast_cli_args::fd, cops_ippool::list, cops_cmts::name, cops_ippool::start, cops_ippool::stop, stop, and ast_cli_entry::usage.
01239 { 01240 struct cops_ippool *ippool; 01241 char start[32]; 01242 char stop[32]; 01243 01244 switch(cmd) { 01245 case CLI_INIT: 01246 e->command = "pktccops show pools"; 01247 e->usage = 01248 "Usage: pktccops show pools\n" 01249 " List PacketCable COPS ip pools of MTAs.\n"; 01250 01251 return NULL; 01252 case CLI_GENERATE: 01253 return NULL; 01254 } 01255 01256 ast_cli(a->fd, "%-16s %-18s %-7s\n", "Start ", "Stop ", "CMTS "); 01257 ast_cli(a->fd, "%-16s %-18s %-7s\n", "----------", "----------", "--------"); 01258 AST_LIST_LOCK(&ippool_list); 01259 AST_LIST_TRAVERSE(&ippool_list, ippool, list) { 01260 snprintf(start, sizeof(start), "%3u.%3u.%3u.%3u", ippool->start >> 24, (ippool->start >> 16) & 0x000000ff, (ippool->start >> 8) & 0x000000ff, ippool->start & 0x000000ff); 01261 01262 snprintf(stop, sizeof(stop), "%3u.%3u.%3u.%3u", ippool->stop >> 24, (ippool->stop >> 16) & 0x000000ff, (ippool->stop >> 8) & 0x000000ff, ippool->stop & 0x000000ff); 01263 ast_cli(a->fd, "%-16s %-18s %-16s\n", start, stop, ippool->cmts->name); 01264 } 01265 AST_LIST_UNLOCK(&ippool_list); 01266 return CLI_SUCCESS; 01267 }
static void pktccops_unregister_cmtses | ( | void | ) | [static] |
Definition at line 1437 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().
01438 { 01439 struct cops_cmts *cmts; 01440 struct cops_gate *gate; 01441 AST_LIST_LOCK(&cmts_list); 01442 while ((cmts = AST_LIST_REMOVE_HEAD(&cmts_list, list))) { 01443 if (cmts->sfd > 0) { 01444 close(cmts->sfd); 01445 } 01446 free(cmts); 01447 } 01448 AST_LIST_UNLOCK(&cmts_list); 01449 01450 AST_LIST_LOCK(&gate_list); 01451 while ((gate = AST_LIST_REMOVE_HEAD(&gate_list, list))) { 01452 free(gate); 01453 } 01454 AST_LIST_UNLOCK(&gate_list); 01455 }
static void pktccops_unregister_ippools | ( | void | ) | [static] |
Definition at line 1457 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().
01458 { 01459 struct cops_ippool *ippool; 01460 AST_LIST_LOCK(&ippool_list); 01461 while ((ippool = AST_LIST_REMOVE_HEAD(&ippool_list, list))) { 01462 free(ippool); 01463 } 01464 AST_LIST_UNLOCK(&ippool_list); 01465 }
static int reload_module | ( | void | ) | [static] |
Definition at line 1503 of file res_pktccops.c.
References ast_log(), LOG_NOTICE, and pktcreload.
01504 { 01505 /* Prohibit unloading */ 01506 if (pktcreload) { 01507 ast_log(LOG_NOTICE, "Previous reload in progress, please wait!\n"); 01508 return -1; 01509 } 01510 pktcreload = 1; 01511 return 0; 01512 }
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 1481 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().
01482 { 01483 if (!ast_mutex_lock(&pktccops_lock)) { 01484 if ((pktccops_thread != AST_PTHREADT_NULL) && (pktccops_thread != AST_PTHREADT_STOP)) { 01485 pthread_cancel(pktccops_thread); 01486 pthread_kill(pktccops_thread, SIGURG); 01487 pthread_join(pktccops_thread, NULL); 01488 } 01489 pktccops_thread = AST_PTHREADT_STOP; 01490 ast_mutex_unlock(&pktccops_lock); 01491 } else { 01492 ast_log(LOG_ERROR, "Unable to lock the pktccops_thread\n"); 01493 return -1; 01494 } 01495 01496 ast_cli_unregister_multiple(cli_pktccops, sizeof(cli_pktccops) / sizeof(struct ast_cli_entry)); 01497 pktccops_unregister_cmtses(); 01498 pktccops_unregister_ippools(); 01499 pktccops_thread = AST_PTHREADT_NULL; 01500 return 0; 01501 }
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 = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .reload = reload_module, } [static] |
Definition at line 1518 of file res_pktccops.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1518 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.