Tue Aug 20 16:35:14 2013

Asterisk developer's documentation


res_pktccops.c File Reference

PacketCable COPS. More...

#include "asterisk.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <arpa/inet.h>
#include <signal.h>
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/options.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/cli.h"
#include "asterisk/lock.h"
#include "asterisk/pktccops.h"

Go to the source code of this file.

Data Structures

struct  cmts_list
struct  cops_cmts
struct  cops_ippool
struct  copsmsg
struct  gate_list
struct  gatespec
struct  ippool_list
struct  pktcobj

Defines

#define AST_API_MODULE
#define COPS_HEADER_SIZE   8
#define COPS_OBJECT_HEADER_SIZE   4
#define DEFAULT_COPS_PORT   "2126"
#define GATE_INFO_OBJ_SIZE   24
#define GATE_SET_OBJ_SIZE   144
#define GATEID_OBJ_SIZE   8
#define PKTCCOPS_DESTROY_CURRENT_GATE
#define PKTCCOPS_SCOMMAND_GATE_ALLOC   1
#define PKTCCOPS_SCOMMAND_GATE_ALLOC_ACK   2
#define PKTCCOPS_SCOMMAND_GATE_ALLOC_ERR   3
#define PKTCCOPS_SCOMMAND_GATE_CLOSE   14
#define PKTCCOPS_SCOMMAND_GATE_DELETE   10
#define PKTCCOPS_SCOMMAND_GATE_DELETE_ACK   11
#define PKTCCOPS_SCOMMAND_GATE_DELETE_ERR   12
#define PKTCCOPS_SCOMMAND_GATE_INFO   7
#define PKTCCOPS_SCOMMAND_GATE_INFO_ACK   8
#define PKTCCOPS_SCOMMAND_GATE_INFO_ERR   9
#define PKTCCOPS_SCOMMAND_GATE_OPEN   13
#define PKTCCOPS_SCOMMAND_GATE_SET   4
#define PKTCCOPS_SCOMMAND_GATE_SET_ACK   5
#define PKTCCOPS_SCOMMAND_GATE_SET_ERR   6
#define SENDFLAGS   MSG_NOSIGNAL | MSG_DONTWAIT

Functions

static void __reg_module (void)
static void __unreg_module (void)
struct cops_gate
*AST_OPTIONAL_API_NAME() 
ast_pktccops_gate_alloc (int cmd, struct cops_gate *gate, uint32_t mta, uint32_t actcount, float bitrate, uint32_t psize, uint32_t ssip, uint16_t ssport, int(*const got_dq_gi)(struct cops_gate *gate), int(*const gate_remove)(struct cops_gate *gate))
static int cops_connect (char *host, char *port)
static uint16_t cops_construct_gate (int cmd, char *p, uint16_t trid, uint32_t mtahost, uint32_t actcount, float rate, uint32_t psizegateid, uint32_t ssip, uint16_t ssport, uint32_t gateid, struct cops_cmts *cmts)
static uint16_t cops_constructgatespec (struct gatespec *gs, char *res)
static void cops_freemsg (struct copsmsg *p)
static struct cops_gatecops_gate_cmd (int cmd, struct cops_cmts *cmts, uint16_t trid, uint32_t mta, uint32_t actcount, float bitrate, uint32_t psize, uint32_t ssip, uint16_t ssport, struct cops_gate *gate)
static int cops_getmsg (int sfd, struct copsmsg *recmsg)
static int cops_sendmsg (int sfd, struct copsmsg *sendmsg)
static void * do_pktccops (void *data)
static uint32_t ftoieeef (float n)
static int load_module (void)
static int load_pktccops_config (void)
static int pktccops_add_ippool (struct cops_ippool *ippool)
static char * pktccops_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * pktccops_gatedel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * pktccops_gateset (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * pktccops_show_cmtses (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * pktccops_show_gates (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * pktccops_show_pools (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void pktccops_unregister_cmtses (void)
static void pktccops_unregister_ippools (void)
static int reload_module (void)
static int restart_pktc_thread (void)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "PktcCOPS manager for MGCP" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload_module, }
static struct ast_module_infoast_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

Detailed Description

PacketCable COPS.

Author:
Attila Domjan <attila.domjan.hu@gmail.com>
Note:
This module is an add-on to chan_mgcp. It adds support for the PacketCable MGCP variation called NCS. Res_pktccops implements COPS (RFC 2748), a protocol used to manage dynamic bandwith allocation in CMTS's (HFC gateways). When you use NCS, you need to talk COPS with the CMTS to complete the calls.

Definition in file res_pktccops.c.


Define Documentation

#define AST_API_MODULE

Definition at line 64 of file res_pktccops.c.

#define COPS_HEADER_SIZE   8

Definition at line 69 of file res_pktccops.c.

Referenced by cops_gate_cmd(), cops_getmsg(), cops_sendmsg(), and do_pktccops().

#define COPS_OBJECT_HEADER_SIZE   4

Definition at line 70 of file res_pktccops.c.

Referenced by cops_gate_cmd(), cops_getmsg(), and do_pktccops().

#define DEFAULT_COPS_PORT   "2126"

Definition at line 67 of file res_pktccops.c.

Referenced by load_pktccops_config().

#define GATE_INFO_OBJ_SIZE   24

Definition at line 73 of file res_pktccops.c.

Referenced by cops_gate_cmd().

#define GATE_SET_OBJ_SIZE   144

Definition at line 71 of file res_pktccops.c.

Referenced by cops_gate_cmd().

#define GATEID_OBJ_SIZE   8

Definition at line 72 of file res_pktccops.c.

Referenced by cops_gate_cmd().

#define PKTCCOPS_DESTROY_CURRENT_GATE
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

Definition at line 88 of file res_pktccops.c.

Referenced by do_pktccops().

#define PKTCCOPS_SCOMMAND_GATE_DELETE   10

Definition at line 84 of file res_pktccops.c.

Referenced by cops_construct_gate().

#define PKTCCOPS_SCOMMAND_GATE_DELETE_ACK   11

Definition at line 85 of file res_pktccops.c.

Referenced by do_pktccops().

#define PKTCCOPS_SCOMMAND_GATE_DELETE_ERR   12

Definition at line 86 of file res_pktccops.c.

#define PKTCCOPS_SCOMMAND_GATE_INFO   7

Definition at line 81 of file res_pktccops.c.

Referenced by cops_construct_gate().

#define PKTCCOPS_SCOMMAND_GATE_INFO_ACK   8

Definition at line 82 of file res_pktccops.c.

Referenced by do_pktccops().

#define PKTCCOPS_SCOMMAND_GATE_INFO_ERR   9

Definition at line 83 of file res_pktccops.c.

Referenced by do_pktccops().

#define PKTCCOPS_SCOMMAND_GATE_OPEN   13

Definition at line 87 of file res_pktccops.c.

Referenced by do_pktccops().

#define PKTCCOPS_SCOMMAND_GATE_SET   4

Definition at line 78 of file res_pktccops.c.

Referenced by cops_construct_gate().

#define PKTCCOPS_SCOMMAND_GATE_SET_ACK   5

Definition at line 79 of file res_pktccops.c.

Referenced by do_pktccops().

#define PKTCCOPS_SCOMMAND_GATE_SET_ERR   6

Definition at line 80 of file res_pktccops.c.

Referenced by do_pktccops().

#define SENDFLAGS   MSG_NOSIGNAL | MSG_DONTWAIT

Referenced by cops_sendmsg().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 1516 of file res_pktccops.c.

static void __unreg_module ( void   )  [static]

Definition at line 1516 of file res_pktccops.c.

struct cops_gate* AST_OPTIONAL_API_NAME() ast_pktccops_gate_alloc ( int  cmd,
struct cops_gate gate,
uint32_t  mta,
uint32_t  actcount,
float  bitrate,
uint32_t  psize,
uint32_t  ssip,
uint16_t  ssport,
int(*)(struct cops_gate *gate)  got_dq_gi,
int(*)(struct cops_gate *gate)  gate_remove 
) [read]

Definition at line 470 of file res_pktccops.c.

References ast_debug, ast_log(), cops_gate_cmd(), cops_gate::gate_remove, GATE_SET_HAVE_GATEID, cops_gate::gateid, cops_gate::got_dq_gi, LOG_WARNING, and pktcreload.

Referenced by mgcp_alloc_pktcgate(), and mgcp_hangup().

00475 {
00476    while (pktcreload) {
00477       sched_yield();
00478    }
00479 
00480    if (cmd == GATE_SET_HAVE_GATEID && gate) {
00481       ast_debug(3, "------- gate modify gateid 0x%x ssip: 0x%x\n", gate->gateid, ssip);
00482       /* TODO implement it */
00483       ast_log(LOG_WARNING, "Modify GateID not implemented\n");
00484    } 
00485    
00486    if ((gate = cops_gate_cmd(cmd, NULL, cops_trid++, mta, actcount, bitrate, psize, ssip, ssport, gate))) {
00487       ast_debug(3, "COPS: Allocating gate for mta: 0x%x\n", mta);
00488       gate->got_dq_gi = got_dq_gi;
00489       gate->gate_remove = gate_remove;
00490       return(gate);
00491    } else {
00492       ast_debug(3, "COPS: Couldn't allocate gate for mta: 0x%x\n", mta); 
00493       return NULL;
00494    }
00495 }

static int cops_connect ( char *  host,
char *  port 
) [static]

Definition at line 651 of file res_pktccops.c.

References ast_debug, ast_log(), and LOG_WARNING.

Referenced by do_pktccops().

00652 {
00653    int s, sfd = -1, flags;
00654    struct addrinfo hints;
00655    struct addrinfo *rp;
00656    struct addrinfo *result;
00657 #ifdef HAVE_SO_NOSIGPIPE
00658    int trueval = 1;
00659 #endif
00660 
00661    memset(&hints, 0, sizeof(struct addrinfo));
00662 
00663    hints.ai_family = AF_UNSPEC;    
00664    hints.ai_socktype = SOCK_STREAM;
00665    hints.ai_flags = 0;
00666    hints.ai_protocol = 0;
00667 
00668    s = getaddrinfo(host, port, &hints, &result);
00669    if (s != 0) {
00670       ast_log(LOG_WARNING, "COPS: getaddrinfo: %s\n", gai_strerror(s));
00671       return -1;
00672    }
00673 
00674    for (rp = result; rp != NULL; rp = rp->ai_next) {
00675       sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
00676       if (sfd == -1) {
00677          ast_log(LOG_WARNING, "Failed socket\n");
00678       }
00679       flags = fcntl(sfd, F_GETFL);
00680       fcntl(sfd, F_SETFL, flags | O_NONBLOCK);
00681 #ifdef HAVE_SO_NOSIGPIPE
00682       setsockopt(sfd, SOL_SOCKET, SO_NOSIGPIPE, &trueval, sizeof(trueval));
00683 #endif
00684       connect(sfd, rp->ai_addr, rp->ai_addrlen);
00685       if (sfd == -1) {
00686          ast_log(LOG_WARNING, "Failed connect\n");
00687       }
00688    }
00689    freeaddrinfo(result);
00690 
00691    ast_debug(3, "Connecting to cmts:  %s:%s\n", host, port);
00692    return(sfd);
00693 }

static uint16_t cops_construct_gate ( int  cmd,
char *  p,
uint16_t  trid,
uint32_t  mtahost,
uint32_t  actcount,
float  rate,
uint32_t  psizegateid,
uint32_t  ssip,
uint16_t  ssport,
uint32_t  gateid,
struct cops_cmts cmts 
) [static]

Definition at line 223 of file res_pktccops.c.

References ast_debug, gatespec::b, cops_constructgatespec(), gatespec::diffserv, gatespec::direction, gatespec::dstip, gatespec::dstp, gatespec::flags, ftoieeef(), GATE_DEL, GATE_INFO, GATE_SET_HAVE_GATEID, gatespec::m, gatespec::mm, gatespec::p, PKTCCOPS_SCOMMAND_GATE_DELETE, PKTCCOPS_SCOMMAND_GATE_INFO, PKTCCOPS_SCOMMAND_GATE_SET, gatespec::protocolid, gatespec::r, gatespec::rate, gatespec::s, gatespec::sessionclass, gatespec::srcip, gatespec::srcp, cops_cmts::t1, gatespec::t1, cops_cmts::t7, gatespec::t7, cops_cmts::t8, and gatespec::t8.

Referenced by cops_gate_cmd().

00226 {
00227    struct gatespec gs;
00228    int offset = 0;
00229    
00230    ast_debug(3, "CMD: %d\n", cmd);
00231 
00232    /* Transaction Identifier 8 octets */
00233    *(p + offset++) = 0;
00234    *(p + offset++) = 8; /* length */
00235    *(p + offset++) = 1; /* snum */
00236    *(p + offset++) = 1; /* stype */
00237    *((uint16_t *) (p + offset)) = htons(trid);
00238    offset += 2;
00239    *(p + offset++) = 0;
00240    *(p + offset++) = (cmd == GATE_DEL) ? PKTCCOPS_SCOMMAND_GATE_DELETE : (cmd != GATE_INFO) ? PKTCCOPS_SCOMMAND_GATE_SET : PKTCCOPS_SCOMMAND_GATE_INFO; /* 4: GATE-SET, 7: GATE-INFO */
00241 
00242    /*Subscriper Identifier 8 octets */
00243    *(p + offset++) = 0;
00244    *(p + offset++) = 8; /* length */
00245    *(p + offset++) = 2; /* snum */
00246    *(p + offset++) = 1; /* stype */
00247    *((uint32_t *) (p + offset)) = htonl(mtahost);
00248    offset += 4;
00249    
00250    if (cmd == GATE_INFO || cmd == GATE_SET_HAVE_GATEID || cmd == GATE_DEL) {
00251       /* Gate ID 8 Octets */
00252       *(p + offset++) = 0;
00253       *(p + offset++) = 8; /* length */
00254       *(p + offset++) = 3; /* snum */
00255       *(p + offset++) = 1; /* stype */
00256       *((uint32_t *) (p + offset)) = htonl(gateid);
00257       offset += 4;
00258       if (cmd == GATE_INFO || cmd == GATE_DEL) {
00259          return offset;
00260       }
00261    
00262    }
00263 
00264    /* Activity Count 8 octets */
00265    *(p + offset++) = 0;
00266    *(p + offset++) = 8; /* length */
00267    *(p + offset++) = 4; /* snum */
00268    *(p + offset++) = 1; /* stype */
00269    *((uint32_t *) (p + offset)) = htonl(actcount);
00270    offset += 4;
00271 
00272 
00273    /* Gate Spec 2*60 Octets */
00274    gs.direction = 0; /* DS */
00275    gs.protocolid = 17; /* UDP */
00276    gs.flags = 0;
00277    gs.sessionclass = 1;
00278    gs.srcip = htonl(ssip);
00279    gs.dstip = htonl(mtahost);
00280    gs.srcp = htons(ssport);
00281    gs.dstp = 0;
00282 /* gs.diffserv = 0xa0;*/
00283    gs.diffserv = 0;
00284    gs.t1 = htons(cmts->t1);
00285    gs.t7 = htons(cmts->t7);
00286    gs.t8 = htons(cmts->t8);
00287    gs.r = ftoieeef(rate);
00288    gs.b = ftoieeef(psizegateid);
00289    gs.p = ftoieeef(rate);
00290    gs.m = htonl((uint32_t) psizegateid);
00291    gs.mm = htonl((uint32_t) psizegateid);
00292    gs.rate = ftoieeef(rate);
00293    gs.s = htonl(800);
00294 
00295 
00296    *(p + offset) = 0;
00297    offset++;
00298    *(p + offset) = 60; /* length */
00299    offset++;
00300    *(p + offset) = 5; /* snum */
00301    offset++;
00302    *(p + offset) = 1; /* stype */
00303    offset++;
00304    offset += cops_constructgatespec(&gs, p + offset);
00305 
00306 
00307    gs.direction = 1; /* US */
00308    gs.srcip = htonl(mtahost);
00309    gs.dstip = htonl(ssip);
00310    gs.srcp = 0;
00311    gs.dstp = htons(ssport);
00312    *(p + offset) = 0;
00313    offset++;
00314    *(p + offset) = 60; /* length */
00315    offset++;
00316    *(p + offset) = 5; /* snum */
00317    offset++;
00318    *(p + offset) = 1; /* stype */
00319    offset++;
00320    offset += cops_constructgatespec(&gs, p + offset);
00321 
00322    return(offset);
00323 }

static uint16_t cops_constructgatespec ( struct gatespec gs,
char *  res 
) [static]

Definition at line 184 of file res_pktccops.c.

References gatespec::b, gatespec::diffserv, gatespec::direction, gatespec::dstip, gatespec::dstp, gatespec::flags, gatespec::m, gatespec::mm, gatespec::p, gatespec::protocolid, gatespec::r, gatespec::rate, gatespec::s, gatespec::sessionclass, gatespec::srcip, gatespec::srcp, gatespec::t1, gatespec::t7, and gatespec::t8.

Referenced by cops_construct_gate().

00185 {
00186    if (res == NULL) {
00187       return 0;
00188    }
00189    
00190    *res = (char) gs->direction;
00191    *(res + 1) = (char) gs->protocolid;
00192    *(res + 2) = (char) gs->flags;
00193    *(res + 3) = (char) gs->sessionclass;
00194 
00195    *((uint32_t *) (res + 4)) = gs->srcip;
00196    *((uint32_t *) (res + 8)) = gs->dstip;
00197 
00198    *((uint16_t *) (res + 12)) = gs->srcp;
00199    *((uint16_t *) (res + 14)) = gs->dstp;
00200 
00201    *(res + 16) = (char) gs->diffserv;
00202    *(res + 17) = 0; /* reserved */
00203    *(res + 18) = 0; /* reserved */
00204    *(res + 19) = 0; /* reserved */
00205 
00206    *((uint16_t *) (res + 20)) = gs->t1;
00207    *(res + 22) = 0; /* reserved */
00208    *(res + 23) = 0; /* reserved */
00209 
00210    *((uint16_t *) (res + 24)) = gs->t7;
00211    *((uint16_t *) (res + 26)) = gs->t8;
00212 
00213    *((uint32_t *) (res + 28)) = gs->r;
00214    *((uint32_t *) (res + 32)) = gs->b;
00215    *((uint32_t *) (res + 36)) = gs->p;
00216    *((uint32_t *) (res + 40)) = gs->m;
00217    *((uint32_t *) (res + 44)) = gs->mm;
00218    *((uint32_t *) (res + 48)) = gs->rate;
00219    *((uint32_t *) (res + 52)) = gs->s;
00220    return 56; /* length */
00221 };

static void cops_freemsg ( struct copsmsg p  )  [static]

Definition at line 455 of file res_pktccops.c.

References ast_free, pktcobj::contents, free, copsmsg::msg, pktcobj::next, and copsmsg::object.

Referenced by cops_gate_cmd(), and do_pktccops().

00456 {
00457    struct pktcobj *pnext;
00458    free(p->msg);
00459    p->msg = NULL;
00460    while (p->object != NULL) {
00461          pnext = p->object->next;
00462          ast_free(p->object->contents);
00463          p->object->contents = NULL;
00464          ast_free(p->object);
00465          p->object = pnext;
00466    }
00467    p->object = NULL;
00468 }

static struct cops_gate * cops_gate_cmd ( int  cmd,
struct cops_cmts cmts,
uint16_t  trid,
uint32_t  mta,
uint32_t  actcount,
float  bitrate,
uint32_t  psize,
uint32_t  ssip,
uint16_t  ssport,
struct cops_gate gate 
) [static, read]

Definition at line 497 of file res_pktccops.c.

References ast_calloc, ast_debug, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), copsmsg::clienttype, cops_ippool::cmts, cops_gate::cmts, pktcobj::cnum, pktcobj::contents, cops_construct_gate(), cops_freemsg(), COPS_HEADER_SIZE, COPS_OBJECT_HEADER_SIZE, cops_sendmsg(), pktcobj::ctype, free, GATE_ALLOC_PROGRESS, GATE_DEL, GATE_INFO, GATE_INFO_OBJ_SIZE, GATE_SET, GATE_SET_HAVE_GATEID, GATE_SET_OBJ_SIZE, cops_gate::gateid, GATEID_OBJ_SIZE, cops_cmts::handle, cops_gate::in_transaction, copsmsg::length, pktcobj::length, LOG_WARNING, malloc, copsmsg::msg, cops_cmts::name, pktcobj::next, copsmsg::object, copsmsg::opcode, pktccopsdebug, cops_cmts::sfd, cops_ippool::start, stop, cops_gate::trid, and copsmsg::verflag.

Referenced by ast_pktccops_gate_alloc(), do_pktccops(), pktccops_gatedel(), and pktccops_gateset().

00500 {
00501    struct copsmsg *gateset;
00502    struct cops_gate *new;
00503    struct cops_ippool *ippool;
00504 
00505    if (cmd == GATE_DEL) {
00506       if (gate == NULL) {
00507          return NULL;
00508       } else {
00509          cmts = gate->cmts;
00510       }
00511    }
00512 
00513    if (!cmts) {
00514       AST_LIST_LOCK(&ippool_list);
00515       AST_LIST_TRAVERSE(&ippool_list, ippool, list) {
00516          if (mta >= ippool->start && mta <= ippool->stop) {
00517             cmts = ippool->cmts;
00518             break;
00519          }
00520       }
00521       AST_LIST_UNLOCK(&ippool_list);
00522       if (!cmts) {
00523          ast_log(LOG_WARNING, "COPS: couldn't find cmts for mta: 0x%x\n", mta);
00524          return NULL;
00525       }
00526       if (cmts->sfd < 0) {
00527          ast_log(LOG_WARNING, "CMTS: %s not connected\n", cmts->name);
00528          return NULL;
00529       }
00530    }
00531 
00532    if (cmd == GATE_SET) {
00533       new = ast_calloc(1, sizeof(*new));
00534       new->gateid = 0;
00535       new->trid = trid;
00536       new->mta = mta;
00537       new->state = GATE_ALLOC_PROGRESS;
00538       new->checked = time(NULL);
00539       new->allocated = time(NULL);
00540       new->cmts = cmts;
00541       new->got_dq_gi = NULL;
00542       new->gate_remove = NULL;
00543       new->gate_open = NULL;
00544       new->tech_pvt = NULL;
00545       new->deltimer = 0;
00546       AST_LIST_LOCK(&gate_list);
00547       AST_LIST_INSERT_HEAD(&gate_list, new, list);
00548       AST_LIST_UNLOCK(&gate_list);
00549       gate = new;
00550    } else {
00551       if (gate) {
00552          gate->trid = trid;
00553       }
00554    }
00555    
00556    gate->in_transaction = time(NULL);
00557 
00558    if (!(gateset = malloc(sizeof(struct copsmsg)))) {
00559       free(gateset);
00560       return NULL;
00561    }
00562    gateset->msg = NULL;
00563    gateset->verflag = 0x10;
00564    gateset->opcode = 2; /* Decision */
00565    gateset->clienttype = 0x8008; /* =PacketCable */
00566    
00567    /* Handle object */
00568    gateset->object = malloc(sizeof(struct pktcobj));
00569    if (!gateset->object) {
00570       cops_freemsg(gateset);
00571       free(gateset);
00572       return NULL;
00573    }
00574    gateset->object->length = COPS_OBJECT_HEADER_SIZE + 4;
00575    gateset->object->cnum = 1; /* Handle */
00576    gateset->object->ctype = 1; /* client */
00577    if (!(gateset->object->contents = malloc(sizeof(uint32_t)))) {
00578       cops_freemsg(gateset);
00579       free(gateset);
00580       return NULL;
00581    }
00582    *((uint32_t *) gateset->object->contents) = htonl(cmts->handle);
00583 
00584    /* Context Object */
00585    if (!(gateset->object->next = malloc(sizeof(struct pktcobj)))) {
00586       cops_freemsg(gateset);
00587       free(gateset);
00588       return NULL;
00589    }
00590    gateset->object->next->length = COPS_OBJECT_HEADER_SIZE + 4;
00591    gateset->object->next->cnum = 2; /* Context */
00592    gateset->object->next->ctype = 1; /* Context */
00593    if (!(gateset->object->next->contents = malloc(sizeof(uint32_t)))) {
00594       cops_freemsg(gateset);
00595       free(gateset);
00596       return NULL;
00597    }
00598    *((uint32_t *) gateset->object->next->contents) = htonl(0x00080000); /* R-Type = 8 configuration request, M-Type = 0 */
00599 
00600    /* Decision Object: Flags */
00601    if (!(gateset->object->next->next = malloc(sizeof(struct pktcobj)))) {
00602       cops_freemsg(gateset);
00603       free(gateset);
00604       return NULL;
00605    }
00606    gateset->object->next->next->length = COPS_OBJECT_HEADER_SIZE + 4;
00607    gateset->object->next->next->cnum = 6; /* Decision */
00608    gateset->object->next->next->ctype = 1; /* Flags */
00609    if (!(gateset->object->next->next->contents = malloc(sizeof(uint32_t)))) {
00610       cops_freemsg(gateset);
00611       free(gateset);
00612       return NULL;
00613    }
00614    *((uint32_t *) gateset->object->next->next->contents) = htonl(0x00010001); /* Install, Trigger Error */
00615 
00616    /* Decision Object: Data */
00617    if (!(gateset->object->next->next->next = malloc(sizeof(struct pktcobj)))) {
00618       cops_freemsg(gateset);
00619       free(gateset);
00620       return NULL;
00621    }
00622    gateset->object->next->next->next->length = COPS_OBJECT_HEADER_SIZE + ((cmd != GATE_INFO && cmd != GATE_DEL) ? GATE_SET_OBJ_SIZE : GATE_INFO_OBJ_SIZE) + ((cmd == GATE_SET_HAVE_GATEID) ? GATEID_OBJ_SIZE : 0);
00623    gateset->object->next->next->next->cnum = 6; /* Decision */
00624    gateset->object->next->next->next->ctype = 4; /* Decision Data */
00625    gateset->object->next->next->next->contents = malloc(((cmd != GATE_INFO && cmd != GATE_DEL) ? GATE_SET_OBJ_SIZE : GATE_INFO_OBJ_SIZE) + ((cmd == GATE_SET_HAVE_GATEID) ? GATEID_OBJ_SIZE : 0));
00626    if (!gateset->object->next->next->next->contents) {
00627       cops_freemsg(gateset);
00628       free(gateset);
00629       return NULL;
00630    }
00631    gateset->object->next->next->next->next = NULL;
00632    
00633    gateset->length = COPS_HEADER_SIZE + gateset->object->length + gateset->object->next->length + gateset->object->next->next->length + gateset->object->next->next->next->length;
00634 
00635    if ((cmd == GATE_INFO || cmd == GATE_SET_HAVE_GATEID || cmd == GATE_DEL) && gate) {
00636       ast_debug(1, "Construct gate with gateid: 0x%x\n", gate->gateid);
00637       cops_construct_gate(cmd, gateset->object->next->next->next->contents, trid, mta, actcount, bitrate, psize, ssip, ssport, gate->gateid, cmts);
00638    } else {
00639       ast_debug(1, "Construct new gate\n");
00640       cops_construct_gate(cmd, gateset->object->next->next->next->contents, trid, mta, actcount, bitrate, psize, ssip, ssport, 0, cmts);
00641    }
00642    if (pktccopsdebug) {
00643       ast_debug(3, "send cmd\n");
00644    }
00645    cops_sendmsg(cmts->sfd, gateset);
00646    cops_freemsg(gateset);
00647    free(gateset);
00648    return gate;
00649 }

static int cops_getmsg ( int  sfd,
struct copsmsg recmsg 
) [static]

Definition at line 325 of file res_pktccops.c.

References ast_debug, copsmsg::clienttype, pktcobj::cnum, pktcobj::contents, COPS_HEADER_SIZE, COPS_OBJECT_HEADER_SIZE, pktcobj::ctype, len(), pktcobj::length, copsmsg::length, malloc, copsmsg::msg, pktcobj::next, copsmsg::object, copsmsg::opcode, and copsmsg::verflag.

Referenced by do_pktccops().

00326 {
00327    int len, lent;
00328    char buf[COPS_HEADER_SIZE];
00329    struct pktcobj *pobject = NULL;
00330    uint16_t *ubuf = (uint16_t *) buf;
00331    recmsg->msg = NULL;
00332    recmsg->object = NULL;
00333    len = recv(sfd, buf, COPS_HEADER_SIZE, MSG_DONTWAIT);
00334    if (len < COPS_HEADER_SIZE) {
00335       return len;
00336    }
00337    recmsg->verflag = *buf;
00338    recmsg->opcode = *(buf + 1);
00339    recmsg->clienttype = ntohs(*((uint16_t *) (buf + 2)));
00340    recmsg->length = ntohl(*((uint32_t *) (buf + 4)));
00341    /* Eg KA msg*/
00342    if (recmsg->clienttype != 0x8008 ) {
00343       if (!(recmsg->msg = malloc(recmsg->length - COPS_HEADER_SIZE))) {
00344          return -1;
00345       }
00346       lent = recv(sfd, recmsg->msg, recmsg->length - COPS_HEADER_SIZE, MSG_DONTWAIT);
00347       if (lent < recmsg->length - COPS_HEADER_SIZE) {
00348          return lent;
00349       }
00350       len += len;
00351    } else {
00352       /* PacketCable Objects */
00353       while (len < recmsg->length) {
00354          if (len == COPS_HEADER_SIZE) {
00355             /* 1st round */
00356             if (!(recmsg->object = malloc(sizeof(struct pktcobj)))) {
00357                return -1;
00358             }
00359             pobject = recmsg->object;
00360          } else {
00361             if (!(pobject->next = malloc(sizeof(struct pktcobj)))) {
00362                return -1;
00363             }
00364             pobject = pobject->next;
00365          }
00366          pobject->next = NULL;
00367          lent = recv(sfd, buf, COPS_OBJECT_HEADER_SIZE, MSG_DONTWAIT);
00368          if (lent < COPS_OBJECT_HEADER_SIZE) {
00369             ast_debug(3, "Too short object header len: %i\n", lent);
00370             return lent;
00371          }
00372          len += lent;
00373          pobject->length = ntohs(*ubuf);
00374          pobject->cnum = *(buf + 2);
00375          pobject->ctype = *(buf + 3);
00376          if (!(pobject->contents = malloc(pobject->length - COPS_OBJECT_HEADER_SIZE))) {
00377             return -1;
00378          }
00379          lent = recv(sfd, pobject->contents, pobject->length - COPS_OBJECT_HEADER_SIZE, MSG_DONTWAIT);
00380          if (lent < pobject->length - COPS_OBJECT_HEADER_SIZE) {
00381             ast_debug(3, "Too short object content len: %i\n", lent);
00382             return lent;
00383          }
00384          len += lent;
00385       }
00386    }
00387    return len;
00388 }

static int cops_sendmsg ( int  sfd,
struct copsmsg sendmsg 
) [static]

Definition at line 390 of file res_pktccops.c.

References ast_debug, ast_log(), copsmsg::clienttype, pktcobj::cnum, pktcobj::contents, COPS_HEADER_SIZE, pktcobj::ctype, errno, free, pktcobj::length, copsmsg::length, LOG_WARNING, malloc, copsmsg::msg, pktcobj::next, copsmsg::object, copsmsg::opcode, SENDFLAGS, and copsmsg::verflag.

Referenced by cops_gate_cmd(), and do_pktccops().

00391 {
00392    char *buf;
00393    int bufpos;
00394    struct pktcobj *pobject;
00395    
00396    if (sfd < 0) {
00397       return -1;
00398    }
00399 
00400    ast_debug(3, "COPS: sending opcode: %i len: %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, 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]

Definition at line 177 of file res_pktccops.c.

Referenced by cops_construct_gate().

00178 {
00179    uint32_t res;
00180    memcpy(&res, &n, 4);
00181    return htonl(res);
00182 }

static int load_module ( void   )  [static]

Definition at line 1465 of file res_pktccops.c.

References ast_cli_register_multiple(), AST_LIST_LOCK, AST_LIST_UNLOCK, AST_MODULE_LOAD_DECLINE, load_pktccops_config(), and restart_pktc_thread().

01466 {
01467    int res;
01468    AST_LIST_LOCK(&cmts_list);
01469    res = load_pktccops_config();
01470    AST_LIST_UNLOCK(&cmts_list);
01471    if (res == -1) {
01472       return AST_MODULE_LOAD_DECLINE;
01473    }
01474    ast_cli_register_multiple(cli_pktccops, sizeof(cli_pktccops) / sizeof(struct ast_cli_entry));
01475    restart_pktc_thread();
01476    return 0;
01477 }

static int load_pktccops_config ( void   )  [static]

Definition at line 1024 of file res_pktccops.c.

References ast_calloc, ast_category_browse(), ast_config_destroy(), ast_config_load, ast_copy_string(), AST_LIST_INSERT_HEAD, AST_LIST_TRAVERSE, ast_log(), ast_variable_browse(), cops_ippool::cmts, config, DEFAULT_COPS_PORT, f, gateinfoperiod, gatetimeout, cops_cmts::host, cops_cmts::keepalive, LOG_WARNING, cops_cmts::name, ast_variable::name, cops_cmts::need_delete, ast_variable::next, pktccops_add_ippool(), cops_cmts::port, cops_cmts::sfd, cops_ippool::start, cops_cmts::state, cops_ippool::stop, cops_cmts::t1, cops_cmts::t7, cops_cmts::t8, update(), and ast_variable::value.

Referenced by do_pktccops(), and load_module().

01025 {
01026    static char *cfg = "res_pktccops.conf";
01027    struct ast_config *config;
01028    struct ast_variable *v;
01029    struct cops_cmts *cmts;
01030    struct cops_ippool *new_ippool;
01031    const char *host, *cat, *port;
01032    int update;
01033    int res = 0;
01034    uint16_t t1_temp, t7_temp, t8_temp;
01035    uint32_t keepalive_temp;
01036    unsigned int a,b,c,d,e,f,g,h;
01037    struct ast_flags config_flags = {0};
01038 
01039    if (!(config = ast_config_load(cfg, config_flags))) {
01040       ast_log(LOG_WARNING, "Unable to load config file res_pktccops.conf\n");
01041       return -1;
01042    }
01043    for (cat = ast_category_browse(config, NULL); cat; cat = ast_category_browse(config, cat)) {
01044       if (!strcmp(cat, "general")) {
01045          for (v = ast_variable_browse(config, cat); v; v = v->next) {
01046             if (!strcasecmp(v->name, "t1")) {
01047                t1 = atoi(v->value);
01048             } else if (!strcasecmp(v->name, "t7")) {
01049                t7 = atoi(v->value);
01050             } else if (!strcasecmp(v->name, "t8")) {
01051                t8 = atoi(v->value);
01052             } else if (!strcasecmp(v->name, "keepalive")) {
01053                keepalive = atoi(v->value);
01054             } else if (!strcasecmp(v->name, "gateinfoperiod")) {
01055                gateinfoperiod = atoi(v->value);
01056             } else if (!strcasecmp(v->name, "gatetimeout")) {
01057                gatetimeout = atoi(v->value);
01058             } else {
01059                ast_log(LOG_WARNING, "Unkown option %s in general section of res_ptkccops.conf\n", v->name);
01060             }
01061          }        
01062       } else {
01063          /* Defaults */
01064          host = NULL;
01065          port = NULL;
01066          t1_temp = t1;
01067          t7_temp = t7;
01068          t8_temp = t8;
01069          keepalive_temp = keepalive;
01070 
01071          for (v = ast_variable_browse(config, cat); v; v = v->next) {
01072             if (!strcasecmp(v->name, "host")) {
01073                host = v->value;           
01074             } else if (!strcasecmp(v->name, "port")) {
01075                port = v->value;
01076             } else if (!strcasecmp(v->name, "t1")) {
01077                t1_temp = atoi(v->value);
01078             } else if (!strcasecmp(v->name, "t7")) {
01079                t7_temp = atoi(v->value);
01080             } else if (!strcasecmp(v->name, "t8")) {
01081                t8_temp = atoi(v->value);
01082             } else if (!strcasecmp(v->name, "keepalive")) {
01083                keepalive_temp = atoi(v->value);
01084             } else if (!strcasecmp(v->name, "pool")) {
01085                /* we weill parse it in 2nd round */
01086             } else {
01087                ast_log(LOG_WARNING, "Unkown option %s in res_ptkccops.conf\n", v->name);
01088             }
01089          }
01090 
01091          update = 0;
01092          AST_LIST_TRAVERSE(&cmts_list, cmts, list) {
01093             if (!strcmp(cmts->name, cat)) {
01094                update = 1;
01095                break;
01096             }
01097 
01098          }
01099          if (!update) {
01100             cmts = ast_calloc(1, sizeof(*cmts));
01101             if (!cmts) {
01102                res = -1;
01103                break;
01104             }
01105             AST_LIST_INSERT_HEAD(&cmts_list, cmts, list);
01106          }
01107          if (cat) {
01108             ast_copy_string(cmts->name, cat, sizeof(cmts->name));
01109          }
01110          if (host) {
01111             ast_copy_string(cmts->host, host, sizeof(cmts->host));
01112          }
01113          if (port) {
01114             ast_copy_string(cmts->port, port, sizeof(cmts->port));
01115          } else {
01116             ast_copy_string(cmts->port, DEFAULT_COPS_PORT, sizeof(cmts->port));
01117          }
01118 
01119          cmts->t1 = t1_temp;
01120          cmts->t7 = t7_temp;
01121          cmts->t8 = t8_temp;
01122          cmts->keepalive = keepalive_temp;
01123          if (!update) {
01124             cmts->state = 0;
01125             cmts->sfd = -1;
01126          }
01127          cmts->need_delete = 0;
01128          for (v = ast_variable_browse(config, cat); v; v = v->next) {
01129             /* parse ipppol when we have cmts ptr */
01130             if (!strcasecmp(v->name, "pool")) {
01131                if (sscanf(v->value, "%3u.%3u.%3u.%3u %3u.%3u.%3u.%3u", &a, &b, &c, &d, &e, &f, &g, &h) == 8) {
01132                   new_ippool = ast_calloc(1, sizeof(*new_ippool));
01133                   if (!new_ippool) {
01134                      res = -1;
01135                      break;
01136                   }
01137                   new_ippool->start = a << 24 | b << 16 | c << 8 | d;
01138                   new_ippool->stop = e << 24 | f << 16 | g << 8 | h;
01139                   new_ippool->cmts = cmts;
01140                   pktccops_add_ippool(new_ippool);
01141                } else {
01142                   ast_log(LOG_WARNING, "Invalid ip pool format in res_pktccops.conf\n");
01143                }
01144             }
01145          }
01146       }
01147    }
01148    ast_config_destroy(config);
01149    return res;
01150 }

static int pktccops_add_ippool ( struct cops_ippool ippool  )  [static]

Definition at line 1422 of file res_pktccops.c.

References AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), and LOG_WARNING.

Referenced by load_pktccops_config().

01423 {
01424    if (ippool) {
01425       AST_LIST_LOCK(&ippool_list);
01426       AST_LIST_INSERT_HEAD(&ippool_list, ippool, list);
01427       AST_LIST_UNLOCK(&ippool_list);
01428       return 0;
01429    } else {
01430       ast_log(LOG_WARNING, "Attempted to register NULL ippool?\n");
01431       return -1;
01432    }
01433 }

static char* pktccops_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1385 of file res_pktccops.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, pktccopsdebug, and ast_cli_entry::usage.

01386 {
01387    switch (cmd) {
01388    case CLI_INIT:
01389       e->command = "pktccops set debug {on|off}";
01390       e->usage = 
01391          "Usage: pktccops set debug {on|off}\n"
01392          "  Turn on/off debuging\n";
01393       return NULL;
01394    case CLI_GENERATE:
01395       return NULL;
01396    }
01397 
01398    if (a->argc != e->args)
01399       return CLI_SHOWUSAGE;
01400    if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
01401       pktccopsdebug = 1;
01402       ast_cli(a->fd, "PktcCOPS Debugging Enabled\n");
01403    } else if (!strncasecmp(a->argv[e->args - 1], "off", 2)) {
01404       pktccopsdebug = 0;
01405       ast_cli(a->fd, "PktcCOPS Debugging Disabled\n");
01406    } else {
01407       return CLI_SHOWUSAGE;
01408    }
01409    return CLI_SUCCESS;
01410 
01411 }

static char* pktccops_gatedel ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1268 of file res_pktccops.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, cops_gate::cmts, ast_cli_entry::command, cops_gate_cmd(), ast_cli_args::fd, GATE_DEL, cops_gate::gateid, cops_cmts::name, and ast_cli_entry::usage.

01269 {
01270    int found = 0;
01271    int trid;
01272    uint32_t gateid;
01273    struct cops_gate *gate;
01274    struct cops_cmts *cmts;
01275 
01276    switch (cmd) {
01277    case CLI_INIT:
01278       e->command = "pktccops gatedel";
01279       e->usage = 
01280          "Usage: pktccops gatedel <cmts> <gateid>\n"
01281          "       Send Gate-Del to cmts.\n";
01282       return NULL;
01283    case CLI_GENERATE:
01284       return NULL;
01285    }
01286 
01287    if (a->argc < 4)
01288       return CLI_SHOWUSAGE;
01289 
01290    AST_LIST_LOCK(&cmts_list);
01291    AST_LIST_TRAVERSE(&cmts_list, cmts, list) {
01292       if (!strcmp(cmts->name, a->argv[2])) {
01293          ast_cli(a->fd, "Found cmts: %s\n", cmts->name);
01294          found = 1;
01295          break;
01296       }
01297    }
01298    AST_LIST_UNLOCK(&cmts_list);
01299    
01300    if (!found)
01301       return CLI_SHOWUSAGE;
01302 
01303    trid = cops_trid++;
01304    if (!sscanf(a->argv[3], "%x", &gateid)) {
01305       ast_cli(a->fd, "bad gate specification (%s)\n", a->argv[3]);   
01306       return CLI_SHOWUSAGE;
01307    }
01308 
01309    found = 0;
01310    AST_LIST_LOCK(&gate_list);
01311    AST_LIST_TRAVERSE(&gate_list, gate, list) {
01312       if (gate->gateid == gateid && gate->cmts == cmts) {
01313          found = 1;
01314          break;
01315       }
01316    }
01317       
01318    if (!found) {
01319       ast_cli(a->fd, "gate not found: %s\n", a->argv[3]);
01320       return CLI_SHOWUSAGE;
01321    }
01322 
01323    AST_LIST_UNLOCK(&gate_list);
01324    cops_gate_cmd(GATE_DEL, cmts, trid, 0, 0, 0, 0, 0, 0, gate);
01325    return CLI_SUCCESS;
01326 }

static char* pktccops_gateset ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1328 of file res_pktccops.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, cops_gate_cmd(), ast_cli_args::fd, GATE_SET, cops_cmts::name, and ast_cli_entry::usage.

01329 {
01330    int foundcmts = 0;
01331    int trid;
01332    unsigned int an,bn,cn,dn;
01333    uint32_t mta, ssip;
01334    struct cops_cmts *cmts;
01335 
01336    switch (cmd) {
01337    case CLI_INIT:
01338       e->command = "pktccops gateset";
01339       e->usage = 
01340          "Usage: pktccops gateset <cmts> <mta> <acctcount> <bitrate> <packet size> <switch ip> <switch port>\n"
01341          "       Send Gate-Set to cmts.\n";
01342       return NULL;
01343    case CLI_GENERATE:
01344       return NULL;
01345    }
01346 
01347    if (a->argc < 9)
01348       return CLI_SHOWUSAGE;
01349 
01350    if (!strncmp(a->argv[2], "null", sizeof(a->argv[2]))) {
01351       cmts = NULL;
01352    } else {
01353       AST_LIST_LOCK(&cmts_list);
01354       AST_LIST_TRAVERSE(&cmts_list, cmts, list) {
01355          if (!strcmp(cmts->name, a->argv[2])) {
01356             ast_cli(a->fd, "Found cmts: %s\n", cmts->name);
01357             foundcmts = 1;
01358             break;
01359          }
01360       }
01361       AST_LIST_UNLOCK(&cmts_list);
01362       if (!foundcmts) {
01363          ast_cli(a->fd, "CMTS not found: %s\n", a->argv[2]);
01364          return CLI_SHOWUSAGE;
01365       }
01366    }
01367 
01368    trid = cops_trid++;
01369    if (sscanf(a->argv[3], "%3u.%3u.%3u.%3u", &an, &bn, &cn, &dn) != 4) {
01370       ast_cli(a->fd, "MTA specification (%s) does not look like an ipaddr\n", a->argv[3]);
01371       return CLI_SHOWUSAGE;
01372    }
01373    mta = an << 24 | bn << 16 | cn << 8 | dn;
01374 
01375    if (sscanf(a->argv[7], "%3u.%3u.%3u.%3u", &an, &bn, &cn, &dn) != 4) {
01376       ast_cli(a->fd, "SSIP specification (%s) does not look like an ipaddr\n", a->argv[7]);
01377       return CLI_SHOWUSAGE;
01378    }
01379    ssip = an << 24 | bn << 16 | cn << 8 | dn;
01380 
01381    cops_gate_cmd(GATE_SET, cmts, trid, mta, atoi(a->argv[4]), atof(a->argv[5]), atoi(a->argv[6]), ssip, atoi(a->argv[8]), NULL);
01382    return CLI_SUCCESS;
01383 }

static char* pktccops_show_cmtses ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1152 of file res_pktccops.c.

References ast_cli(), ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, cops_cmts::host, cops_cmts::katimer, cops_cmts::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_cmts::name, cops_ippool::start, cops_ippool::stop, stop, and ast_cli_entry::usage.

01238 {
01239    struct cops_ippool *ippool;
01240    char start[32];
01241    char stop[32];
01242 
01243    switch(cmd) {
01244    case CLI_INIT:
01245       e->command = "pktccops show pools";
01246       e->usage = 
01247          "Usage: pktccops show pools\n"
01248          "       List PacketCable COPS ip pools of MTAs.\n";
01249 
01250       return NULL;
01251    case CLI_GENERATE:
01252       return NULL;
01253    }
01254 
01255    ast_cli(a->fd, "%-16s %-18s %-7s\n", "Start     ", "Stop      ", "CMTS    ");
01256    ast_cli(a->fd, "%-16s %-18s %-7s\n", "----------", "----------", "--------");
01257    AST_LIST_LOCK(&ippool_list);
01258    AST_LIST_TRAVERSE(&ippool_list, ippool, list) {
01259       snprintf(start, sizeof(start), "%3u.%3u.%3u.%3u", ippool->start >> 24, (ippool->start >> 16) & 0x000000ff, (ippool->start >> 8) & 0x000000ff, ippool->start & 0x000000ff);
01260 
01261       snprintf(stop, sizeof(stop), "%3u.%3u.%3u.%3u", ippool->stop >> 24, (ippool->stop >> 16) & 0x000000ff, (ippool->stop >> 8) & 0x000000ff, ippool->stop & 0x000000ff);
01262       ast_cli(a->fd, "%-16s %-18s %-16s\n", start, stop, ippool->cmts->name);
01263    }
01264    AST_LIST_UNLOCK(&ippool_list);
01265    return CLI_SUCCESS;
01266 }

static void pktccops_unregister_cmtses ( void   )  [static]

Definition at line 1435 of file res_pktccops.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free, and cops_cmts::sfd.

Referenced by unload_module().

01436 {
01437    struct cops_cmts *cmts;
01438    struct cops_gate *gate;
01439    AST_LIST_LOCK(&cmts_list);
01440    while ((cmts = AST_LIST_REMOVE_HEAD(&cmts_list, list))) {
01441       if (cmts->sfd > 0) {
01442          close(cmts->sfd);
01443       }
01444       free(cmts);
01445    }
01446    AST_LIST_UNLOCK(&cmts_list);
01447 
01448    AST_LIST_LOCK(&gate_list);
01449    while ((gate = AST_LIST_REMOVE_HEAD(&gate_list, list))) {
01450       free(gate);
01451    }
01452    AST_LIST_UNLOCK(&gate_list);
01453 }

static void pktccops_unregister_ippools ( void   )  [static]

Definition at line 1455 of file res_pktccops.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free.

Referenced by do_pktccops(), and unload_module().

01456 {
01457    struct cops_ippool *ippool;
01458    AST_LIST_LOCK(&ippool_list);
01459    while ((ippool = AST_LIST_REMOVE_HEAD(&ippool_list, list))) {
01460       free(ippool);
01461    }
01462    AST_LIST_UNLOCK(&ippool_list);
01463 }

static int reload_module ( void   )  [static]

Definition at line 1501 of file res_pktccops.c.

References ast_log(), LOG_NOTICE, and pktcreload.

01502 {
01503    /* Prohibit unloading */
01504    if (pktcreload) {
01505       ast_log(LOG_NOTICE, "Previous reload in progress, please wait!\n");
01506       return -1;
01507    }
01508    pktcreload = 1;
01509    return 0;
01510 }

static int restart_pktc_thread ( void   )  [static]

Definition at line 995 of file res_pktccops.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_pktccops(), LOG_ERROR, LOG_WARNING, and pktccops_lock.

Referenced by load_module().

00996 {
00997    if (pktccops_thread == AST_PTHREADT_STOP) {
00998       return 0;
00999    }
01000    if (ast_mutex_lock(&pktccops_lock)) {
01001       ast_log(LOG_WARNING, "Unable to lock pktccops\n");
01002       return -1;
01003    }
01004    if (pktccops_thread == pthread_self()) {
01005       ast_mutex_unlock(&pktccops_lock);
01006       ast_log(LOG_WARNING, "Cannot kill myself\n");
01007       return -1;
01008    }
01009    if (pktccops_thread != AST_PTHREADT_NULL) {
01010       /* Wake up the thread */
01011       pthread_kill(pktccops_thread, SIGURG);
01012    } else {
01013       /* Start a new monitor */
01014       if (ast_pthread_create_background(&pktccops_thread, NULL, do_pktccops, NULL) < 0) {
01015          ast_mutex_unlock(&pktccops_lock);
01016          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
01017          return -1;
01018       }
01019    }
01020    ast_mutex_unlock(&pktccops_lock);
01021    return 0;
01022 }

static int unload_module ( void   )  [static]

Definition at line 1479 of file res_pktccops.c.

References ast_cli_unregister_multiple(), ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_PTHREADT_STOP, LOG_ERROR, pktccops_lock, pktccops_unregister_cmtses(), and pktccops_unregister_ippools().

01480 {
01481    if (!ast_mutex_lock(&pktccops_lock)) {
01482       if ((pktccops_thread != AST_PTHREADT_NULL) && (pktccops_thread != AST_PTHREADT_STOP)) {
01483          pthread_cancel(pktccops_thread);
01484          pthread_kill(pktccops_thread, SIGURG);
01485          pthread_join(pktccops_thread, NULL);
01486       }
01487       pktccops_thread = AST_PTHREADT_STOP;
01488       ast_mutex_unlock(&pktccops_lock);
01489    } else {
01490       ast_log(LOG_ERROR, "Unable to lock the pktccops_thread\n");
01491       return -1;
01492    }
01493 
01494    ast_cli_unregister_multiple(cli_pktccops, sizeof(cli_pktccops) / sizeof(struct ast_cli_entry));
01495    pktccops_unregister_cmtses();
01496    pktccops_unregister_ippools();
01497    pktccops_thread = AST_PTHREADT_NULL;
01498    return 0;
01499 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "PktcCOPS manager for MGCP" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload_module, } [static]

Definition at line 1516 of file res_pktccops.c.

Definition at line 1516 of file res_pktccops.c.

struct ast_cli_entry cli_pktccops[] [static]

Definition at line 1413 of file res_pktccops.c.

uint16_t cops_trid = 0 [static]

Definition at line 92 of file res_pktccops.c.

int gateinfoperiod = 60 [static]

Definition at line 165 of file res_pktccops.c.

Referenced by do_pktccops(), and load_pktccops_config().

int gatetimeout = 150 [static]

Definition at line 166 of file res_pktccops.c.

Referenced by do_pktccops(), and load_pktccops_config().

uint32_t keepalive = 60 [static]

Definition at line 162 of file res_pktccops.c.

ast_mutex_t pktccops_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static]

Definition at line 90 of file res_pktccops.c.

Referenced by restart_pktc_thread(), and unload_module().

pthread_t pktccops_thread = AST_PTHREADT_NULL [static]

Definition at line 91 of file res_pktccops.c.

int pktccopsdebug = 0 [static]

Definition at line 163 of file res_pktccops.c.

Referenced by cops_gate_cmd(), and pktccops_debug().

int pktcreload = 0 [static]

Definition at line 164 of file res_pktccops.c.

Referenced by ast_pktccops_gate_alloc(), do_pktccops(), and reload_module().

uint16_t t1 = 250 [static]

Definition at line 159 of file res_pktccops.c.

Referenced by dahdi_bridge(), and is_prefix().

uint16_t t7 = 200 [static]

Definition at line 160 of file res_pktccops.c.

uint16_t t8 = 300 [static]

Definition at line 161 of file res_pktccops.c.


Generated on 20 Aug 2013 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1