Mon Mar 12 2012 21:44:52

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"
Include dependency graph for res_pktccops.c:

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 = AST_BUILDOPT_SUM, .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 []
struct cmts_list cmts_list
static uint16_t cops_trid = 0
struct gate_list gate_list
static int gateinfoperiod = 60
static int gatetimeout = 150
struct ippool_list ippool_list
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 63 of file res_pktccops.c.

#define COPS_HEADER_SIZE   8

Definition at line 68 of file res_pktccops.c.

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

#define COPS_OBJECT_HEADER_SIZE   4

Definition at line 69 of file res_pktccops.c.

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

#define DEFAULT_COPS_PORT   "2126"

Definition at line 66 of file res_pktccops.c.

Referenced by load_pktccops_config().

#define GATE_INFO_OBJ_SIZE   24

Definition at line 72 of file res_pktccops.c.

Referenced by cops_gate_cmd().

#define GATE_SET_OBJ_SIZE   144

Definition at line 70 of file res_pktccops.c.

Referenced by cops_gate_cmd().

#define GATEID_OBJ_SIZE   8

Definition at line 71 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 694 of file res_pktccops.c.

Referenced by do_pktccops().

#define PKTCCOPS_SCOMMAND_GATE_ALLOC   1

Definition at line 74 of file res_pktccops.c.

#define PKTCCOPS_SCOMMAND_GATE_ALLOC_ACK   2

Definition at line 75 of file res_pktccops.c.

#define PKTCCOPS_SCOMMAND_GATE_ALLOC_ERR   3

Definition at line 76 of file res_pktccops.c.

#define PKTCCOPS_SCOMMAND_GATE_CLOSE   14

Definition at line 87 of file res_pktccops.c.

Referenced by do_pktccops().

#define PKTCCOPS_SCOMMAND_GATE_DELETE   10

Definition at line 83 of file res_pktccops.c.

Referenced by cops_construct_gate().

#define PKTCCOPS_SCOMMAND_GATE_DELETE_ACK   11

Definition at line 84 of file res_pktccops.c.

Referenced by do_pktccops().

#define PKTCCOPS_SCOMMAND_GATE_DELETE_ERR   12

Definition at line 85 of file res_pktccops.c.

#define PKTCCOPS_SCOMMAND_GATE_INFO   7

Definition at line 80 of file res_pktccops.c.

Referenced by cops_construct_gate().

#define PKTCCOPS_SCOMMAND_GATE_INFO_ACK   8

Definition at line 81 of file res_pktccops.c.

Referenced by do_pktccops().

#define PKTCCOPS_SCOMMAND_GATE_INFO_ERR   9

Definition at line 82 of file res_pktccops.c.

Referenced by do_pktccops().

#define PKTCCOPS_SCOMMAND_GATE_OPEN   13

Definition at line 86 of file res_pktccops.c.

Referenced by do_pktccops().

#define PKTCCOPS_SCOMMAND_GATE_SET   4

Definition at line 77 of file res_pktccops.c.

Referenced by cops_construct_gate().

#define PKTCCOPS_SCOMMAND_GATE_SET_ACK   5

Definition at line 78 of file res_pktccops.c.

Referenced by do_pktccops().

#define PKTCCOPS_SCOMMAND_GATE_SET_ERR   6

Definition at line 79 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 1517 of file res_pktccops.c.

static void __unreg_module ( void  ) [static]

Definition at line 1517 of file res_pktccops.c.

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

Definition at line 469 of file res_pktccops.c.

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

Referenced by mgcp_alloc_pktcgate(), and mgcp_hangup().

{
   while (pktcreload) {
      sched_yield();
   }

   if (cmd == GATE_SET_HAVE_GATEID && gate) {
      ast_debug(3, "------- gate modify gateid 0x%x ssip: 0x%x\n", gate->gateid, ssip);
      /* TODO implement it */
      ast_log(LOG_WARNING, "Modify GateID not implemented\n");
   } 
   
   if ((gate = cops_gate_cmd(cmd, NULL, cops_trid++, mta, actcount, bitrate, psize, ssip, ssport, gate))) {
      ast_debug(3, "COPS: Allocating gate for mta: 0x%x\n", mta);
      gate->got_dq_gi = got_dq_gi;
      gate->gate_remove = gate_remove;
      return(gate);
   } else {
      ast_debug(3, "COPS: Couldn't allocate gate for mta: 0x%x\n", mta); 
      return NULL;
   }
}
static int cops_connect ( char *  host,
char *  port 
) [static]

Definition at line 650 of file res_pktccops.c.

References ast_debug, ast_log(), and LOG_WARNING.

Referenced by do_pktccops().

{
   int s, sfd = -1, flags;
   struct addrinfo hints;
   struct addrinfo *rp;
   struct addrinfo *result;
#ifdef HAVE_SO_NOSIGPIPE
   int trueval = 1;
#endif

   memset(&hints, 0, sizeof(struct addrinfo));

   hints.ai_family = AF_UNSPEC;    
   hints.ai_socktype = SOCK_STREAM;
   hints.ai_flags = 0;
   hints.ai_protocol = 0;

   s = getaddrinfo(host, port, &hints, &result);
   if (s != 0) {
      ast_log(LOG_WARNING, "COPS: getaddrinfo: %s\n", gai_strerror(s));
      return -1;
   }

   for (rp = result; rp != NULL; rp = rp->ai_next) {
      sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
      if (sfd == -1) {
         ast_log(LOG_WARNING, "Failed socket\n");
      }
      flags = fcntl(sfd, F_GETFL);
      fcntl(sfd, F_SETFL, flags | O_NONBLOCK);
#ifdef HAVE_SO_NOSIGPIPE
      setsockopt(sfd, SOL_SOCKET, SO_NOSIGPIPE, &trueval, sizeof(trueval));
#endif
      connect(sfd, rp->ai_addr, rp->ai_addrlen);
      if (sfd == -1) {
         ast_log(LOG_WARNING, "Failed connect\n");
      }
   }
   freeaddrinfo(result);

   ast_debug(3, "Connecting to cmts:  %s:%s\n", host, port);
   return(sfd);
}
static uint16_t cops_construct_gate ( int  cmd,
char *  p,
uint16_t  trid,
uint32_t  mtahost,
uint32_t  actcount,
float  rate,
uint32_t  psizegateid,
uint32_t  ssip,
uint16_t  ssport,
uint32_t  gateid,
struct cops_cmts cmts 
) [static]

Definition at line 222 of file res_pktccops.c.

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

Referenced by cops_gate_cmd().

{
   struct gatespec gs;
   int offset = 0;
   
   ast_debug(3, "CMD: %d\n", cmd);

   /* Transaction Identifier 8 octets */
   *(p + offset++) = 0;
   *(p + offset++) = 8; /* length */
   *(p + offset++) = 1; /* snum */
   *(p + offset++) = 1; /* stype */
   *((uint16_t *) (p + offset)) = htons(trid);
   offset += 2;
   *(p + offset++) = 0;
   *(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 */

   /*Subscriper Identifier 8 octets */
   *(p + offset++) = 0;
   *(p + offset++) = 8; /* length */
   *(p + offset++) = 2; /* snum */
   *(p + offset++) = 1; /* stype */
   *((uint32_t *) (p + offset)) = htonl(mtahost);
   offset += 4;
   
   if (cmd == GATE_INFO || cmd == GATE_SET_HAVE_GATEID || cmd == GATE_DEL) {
      /* Gate ID 8 Octets */
      *(p + offset++) = 0;
      *(p + offset++) = 8; /* length */
      *(p + offset++) = 3; /* snum */
      *(p + offset++) = 1; /* stype */
      *((uint32_t *) (p + offset)) = htonl(gateid);
      offset += 4;
      if (cmd == GATE_INFO || cmd == GATE_DEL) {
         return offset;
      }
   
   }

   /* Activity Count 8 octets */
   *(p + offset++) = 0;
   *(p + offset++) = 8; /* length */
   *(p + offset++) = 4; /* snum */
   *(p + offset++) = 1; /* stype */
   *((uint32_t *) (p + offset)) = htonl(actcount);
   offset += 4;


   /* Gate Spec 2*60 Octets */
   gs.direction = 0; /* DS */
   gs.protocolid = 17; /* UDP */
   gs.flags = 0;
   gs.sessionclass = 1;
   gs.srcip = htonl(ssip);
   gs.dstip = htonl(mtahost);
   gs.srcp = htons(ssport);
   gs.dstp = 0;
/* gs.diffserv = 0xa0;*/
   gs.diffserv = 0;
   gs.t1 = htons(cmts->t1);
   gs.t7 = htons(cmts->t7);
   gs.t8 = htons(cmts->t8);
   gs.r = ftoieeef(rate);
   gs.b = ftoieeef(psizegateid);
   gs.p = ftoieeef(rate);
   gs.m = htonl((uint32_t) psizegateid);
   gs.mm = htonl((uint32_t) psizegateid);
   gs.rate = ftoieeef(rate);
   gs.s = htonl(800);


   *(p + offset) = 0;
   offset++;
   *(p + offset) = 60; /* length */
   offset++;
   *(p + offset) = 5; /* snum */
   offset++;
   *(p + offset) = 1; /* stype */
   offset++;
   offset += cops_constructgatespec(&gs, p + offset);


   gs.direction = 1; /* US */
   gs.srcip = htonl(mtahost);
   gs.dstip = htonl(ssip);
   gs.srcp = 0;
   gs.dstp = htons(ssport);
   *(p + offset) = 0;
   offset++;
   *(p + offset) = 60; /* length */
   offset++;
   *(p + offset) = 5; /* snum */
   offset++;
   *(p + offset) = 1; /* stype */
   offset++;
   offset += cops_constructgatespec(&gs, p + offset);

   return(offset);
}
static uint16_t cops_constructgatespec ( struct gatespec gs,
char *  res 
) [static]

Definition at line 183 of file res_pktccops.c.

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

Referenced by cops_construct_gate().

{
   if (res == NULL) {
      return 0;
   }
   
   *res = (char) gs->direction;
   *(res + 1) = (char) gs->protocolid;
   *(res + 2) = (char) gs->flags;
   *(res + 3) = (char) gs->sessionclass;

   *((uint32_t *) (res + 4)) = gs->srcip;
   *((uint32_t *) (res + 8)) = gs->dstip;

   *((uint16_t *) (res + 12)) = gs->srcp;
   *((uint16_t *) (res + 14)) = gs->dstp;

   *(res + 16) = (char) gs->diffserv;
   *(res + 17) = 0; /* reserved */
   *(res + 18) = 0; /* reserved */
   *(res + 19) = 0; /* reserved */

   *((uint16_t *) (res + 20)) = gs->t1;
   *(res + 22) = 0; /* reserved */
   *(res + 23) = 0; /* reserved */

   *((uint16_t *) (res + 24)) = gs->t7;
   *((uint16_t *) (res + 26)) = gs->t8;

   *((uint32_t *) (res + 28)) = gs->r;
   *((uint32_t *) (res + 32)) = gs->b;
   *((uint32_t *) (res + 36)) = gs->p;
   *((uint32_t *) (res + 40)) = gs->m;
   *((uint32_t *) (res + 44)) = gs->mm;
   *((uint32_t *) (res + 48)) = gs->rate;
   *((uint32_t *) (res + 52)) = gs->s;
   return 56; /* length */
};
static void cops_freemsg ( struct copsmsg p) [static]

Definition at line 454 of file res_pktccops.c.

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

Referenced by cops_gate_cmd(), and do_pktccops().

{
   struct pktcobj *pnext;
   free(p->msg);
   p->msg = NULL;
   while (p->object != NULL) {
         pnext = p->object->next;
         ast_free(p->object->contents);
         p->object->contents = NULL;
         ast_free(p->object);
         p->object = pnext;
   }
   p->object = NULL;
}
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 496 of file res_pktccops.c.

References ast_calloc, ast_debug, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), copsmsg::clienttype, cops_gate::cmts, cops_ippool::cmts, pktcobj::cnum, pktcobj::contents, cops_construct_gate(), cops_freemsg(), COPS_HEADER_SIZE, COPS_OBJECT_HEADER_SIZE, cops_sendmsg(), pktcobj::ctype, free, GATE_ALLOC_PROGRESS, GATE_DEL, GATE_INFO, GATE_INFO_OBJ_SIZE, GATE_SET, GATE_SET_HAVE_GATEID, GATE_SET_OBJ_SIZE, cops_gate::gateid, GATEID_OBJ_SIZE, cops_cmts::handle, cops_gate::in_transaction, pktcobj::length, copsmsg::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().

{
   struct copsmsg *gateset;
   struct cops_gate *new;
   struct cops_ippool *ippool;

   if (cmd == GATE_DEL) {
      if (gate == NULL) {
         return NULL;
      } else {
         cmts = gate->cmts;
      }
   }

   if (!cmts) {
      AST_LIST_LOCK(&ippool_list);
      AST_LIST_TRAVERSE(&ippool_list, ippool, list) {
         if (mta >= ippool->start && mta <= ippool->stop) {
            cmts = ippool->cmts;
            break;
         }
      }
      AST_LIST_UNLOCK(&ippool_list);
      if (!cmts) {
         ast_log(LOG_WARNING, "COPS: couldn't find cmts for mta: 0x%x\n", mta);
         return NULL;
      }
      if (cmts->sfd < 0) {
         ast_log(LOG_WARNING, "CMTS: %s not connected\n", cmts->name);
         return NULL;
      }
   }

   if (cmd == GATE_SET) {
      new = ast_calloc(1, sizeof(*new));
      new->gateid = 0;
      new->trid = trid;
      new->mta = mta;
      new->state = GATE_ALLOC_PROGRESS;
      new->checked = time(NULL);
      new->allocated = time(NULL);
      new->cmts = cmts;
      new->got_dq_gi = NULL;
      new->gate_remove = NULL;
      new->gate_open = NULL;
      new->tech_pvt = NULL;
      new->deltimer = 0;
      AST_LIST_LOCK(&gate_list);
      AST_LIST_INSERT_HEAD(&gate_list, new, list);
      AST_LIST_UNLOCK(&gate_list);
      gate = new;
   } else {
      if (gate) {
         gate->trid = trid;
      }
   }
   
   gate->in_transaction = time(NULL);

   if (!(gateset = malloc(sizeof(struct copsmsg)))) {
      free(gateset);
      return NULL;
   }
   gateset->msg = NULL;
   gateset->verflag = 0x10;
   gateset->opcode = 2; /* Decision */
   gateset->clienttype = 0x8008; /* =PacketCable */
   
   /* Handle object */
   gateset->object = malloc(sizeof(struct pktcobj));
   if (!gateset->object) {
      cops_freemsg(gateset);
      free(gateset);
      return NULL;
   }
   gateset->object->length = COPS_OBJECT_HEADER_SIZE + 4;
   gateset->object->cnum = 1; /* Handle */
   gateset->object->ctype = 1; /* client */
   if (!(gateset->object->contents = malloc(sizeof(uint32_t)))) {
      cops_freemsg(gateset);
      free(gateset);
      return NULL;
   }
   *((uint32_t *) gateset->object->contents) = htonl(cmts->handle);

   /* Context Object */
   if (!(gateset->object->next = malloc(sizeof(struct pktcobj)))) {
      cops_freemsg(gateset);
      free(gateset);
      return NULL;
   }
   gateset->object->next->length = COPS_OBJECT_HEADER_SIZE + 4;
   gateset->object->next->cnum = 2; /* Context */
   gateset->object->next->ctype = 1; /* Context */
   if (!(gateset->object->next->contents = malloc(sizeof(uint32_t)))) {
      cops_freemsg(gateset);
      free(gateset);
      return NULL;
   }
   *((uint32_t *) gateset->object->next->contents) = htonl(0x00080000); /* R-Type = 8 configuration request, M-Type = 0 */

   /* Decision Object: Flags */
   if (!(gateset->object->next->next = malloc(sizeof(struct pktcobj)))) {
      cops_freemsg(gateset);
      free(gateset);
      return NULL;
   }
   gateset->object->next->next->length = COPS_OBJECT_HEADER_SIZE + 4;
   gateset->object->next->next->cnum = 6; /* Decision */
   gateset->object->next->next->ctype = 1; /* Flags */
   if (!(gateset->object->next->next->contents = malloc(sizeof(uint32_t)))) {
      cops_freemsg(gateset);
      free(gateset);
      return NULL;
   }
   *((uint32_t *) gateset->object->next->next->contents) = htonl(0x00010001); /* Install, Trigger Error */

   /* Decision Object: Data */
   if (!(gateset->object->next->next->next = malloc(sizeof(struct pktcobj)))) {
      cops_freemsg(gateset);
      free(gateset);
      return NULL;
   }
   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);
   gateset->object->next->next->next->cnum = 6; /* Decision */
   gateset->object->next->next->next->ctype = 4; /* Decision Data */
   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));
   if (!gateset->object->next->next->next->contents) {
      cops_freemsg(gateset);
      free(gateset);
      return NULL;
   }
   gateset->object->next->next->next->next = NULL;
   
   gateset->length = COPS_HEADER_SIZE + gateset->object->length + gateset->object->next->length + gateset->object->next->next->length + gateset->object->next->next->next->length;

   if ((cmd == GATE_INFO || cmd == GATE_SET_HAVE_GATEID || cmd == GATE_DEL) && gate) {
      ast_debug(1, "Construct gate with gateid: 0x%x\n", gate->gateid);
      cops_construct_gate(cmd, gateset->object->next->next->next->contents, trid, mta, actcount, bitrate, psize, ssip, ssport, gate->gateid, cmts);
   } else {
      ast_debug(1, "Construct new gate\n");
      cops_construct_gate(cmd, gateset->object->next->next->next->contents, trid, mta, actcount, bitrate, psize, ssip, ssport, 0, cmts);
   }
   if (pktccopsdebug) {
      ast_debug(3, "send cmd\n");
   }
   cops_sendmsg(cmts->sfd, gateset);
   cops_freemsg(gateset);
   free(gateset);
   return gate;
}
static int cops_getmsg ( int  sfd,
struct copsmsg recmsg 
) [static]

Definition at line 324 of file res_pktccops.c.

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

Referenced by do_pktccops().

{
   int len, lent;
   char buf[COPS_HEADER_SIZE];
   struct pktcobj *pobject = NULL;
   uint16_t *ubuf = (uint16_t *) buf;
   recmsg->msg = NULL;
   recmsg->object = NULL;
   len = recv(sfd, buf, COPS_HEADER_SIZE, MSG_DONTWAIT);
   if (len < COPS_HEADER_SIZE) {
      return len;
   }
   recmsg->verflag = *buf;
   recmsg->opcode = *(buf + 1);
   recmsg->clienttype = ntohs(*((uint16_t *) (buf + 2)));
   recmsg->length = ntohl(*((uint32_t *) (buf + 4)));
   /* Eg KA msg*/
   if (recmsg->clienttype != 0x8008 ) {
      if (!(recmsg->msg = malloc(recmsg->length - COPS_HEADER_SIZE))) {
         return -1;
      }
      lent = recv(sfd, recmsg->msg, recmsg->length - COPS_HEADER_SIZE, MSG_DONTWAIT);
      if (lent < recmsg->length - COPS_HEADER_SIZE) {
         return lent;
      }
      len += len;
   } else {
      /* PacketCable Objects */
      while (len < recmsg->length) {
         if (len == COPS_HEADER_SIZE) {
            /* 1st round */
            if (!(recmsg->object = malloc(sizeof(struct pktcobj)))) {
               return -1;
            }
            pobject = recmsg->object;
         } else {
            if (!(pobject->next = malloc(sizeof(struct pktcobj)))) {
               return -1;
            }
            pobject = pobject->next;
         }
         pobject->next = NULL;
         lent = recv(sfd, buf, COPS_OBJECT_HEADER_SIZE, MSG_DONTWAIT);
         if (lent < COPS_OBJECT_HEADER_SIZE) {
            ast_debug(3, "Too short object header len: %i\n", lent);
            return lent;
         }
         len += lent;
         pobject->length = ntohs(*ubuf);
         pobject->cnum = *(buf + 2);
         pobject->ctype = *(buf + 3);
         if (!(pobject->contents = malloc(pobject->length - COPS_OBJECT_HEADER_SIZE))) {
            return -1;
         }
         lent = recv(sfd, pobject->contents, pobject->length - COPS_OBJECT_HEADER_SIZE, MSG_DONTWAIT);
         if (lent < pobject->length - COPS_OBJECT_HEADER_SIZE) {
            ast_debug(3, "Too short object content len: %i\n", lent);
            return lent;
         }
         len += lent;
      }
   }
   return len;
}
static int cops_sendmsg ( int  sfd,
struct copsmsg sendmsg 
) [static]

Definition at line 389 of file res_pktccops.c.

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

Referenced by cops_gate_cmd(), and do_pktccops().

{
   char *buf;
   int bufpos;
   struct pktcobj *pobject;
   
   if (sfd < 0) {
      return -1;
   }

   ast_debug(3, "COPS: sending opcode: %i len: %i\n", sendmsg->opcode, sendmsg->length);
   if (sendmsg->length < COPS_HEADER_SIZE) {
      ast_log(LOG_WARNING, "COPS: invalid msg size!!!\n");
      return -1;
   }
   if (!(buf = malloc((size_t) sendmsg->length))) {
      return -1;
   }
   *buf = sendmsg->verflag ;
   *(buf + 1) = sendmsg->opcode;
   *((uint16_t *)(buf + 2)) = htons(sendmsg->clienttype);
   *((uint32_t *)(buf + 4)) = htonl(sendmsg->length);

   if (sendmsg->msg != NULL) {
      memcpy(buf + COPS_HEADER_SIZE, sendmsg->msg, sendmsg->length - COPS_HEADER_SIZE);
   } else if (sendmsg->object != NULL) {
      bufpos = 8;
      pobject = sendmsg->object;
      while(pobject != NULL) {
         ast_debug(3, "COPS: Sending Object : cnum: %i ctype %i len: %i\n", pobject->cnum, pobject->ctype, pobject->length);
         if (sendmsg->length < bufpos + pobject->length) {
            ast_log(LOG_WARNING, "COPS: Invalid msg size len: %i objectlen: %i\n", sendmsg->length, pobject->length);
            free(buf);
            return -1;
         }
         *(uint16_t *) (buf + bufpos) = htons(pobject->length);
         *(buf + bufpos + 2) = pobject->cnum;
         *(buf + bufpos + 3) = pobject->ctype;
         if (sendmsg->length < pobject->length + bufpos) {
            ast_log(LOG_WARNING, "COPS: Error sum of object len more the msg len %i < %i\n", sendmsg->length, pobject->length + bufpos);
            free(buf);
            return -1;
         }
         memcpy((buf + bufpos + 4), pobject->contents, pobject->length - 4);
         bufpos += pobject->length;
         pobject = pobject->next;
      }
   }
   
   errno = 0;
#ifdef HAVE_MSG_NOSIGNAL
#define  SENDFLAGS   MSG_NOSIGNAL | MSG_DONTWAIT
#else
#define  SENDFLAGS   MSG_DONTWAIT
#endif
   if (send(sfd, buf, sendmsg->length, SENDFLAGS) == -1) {
      ast_log(LOG_WARNING, "COPS: Send failed errno=%i\n", errno);
      free(buf);
      return -2;
   }
#undef SENDFLAGS
   free(buf);
   return 0;
}
static void* do_pktccops ( void *  data) [static]

Definition at line 701 of file res_pktccops.c.

References ast_debug, ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_poll, ast_poll_fd_index(), ast_realloc, cops_gate::checked, copsmsg::clienttype, cops_gate::cmts, pktcobj::cnum, pktcobj::contents, cops_connect(), cops_freemsg(), cops_gate_cmd(), cops_getmsg(), COPS_HEADER_SIZE, COPS_OBJECT_HEADER_SIZE, cops_sendmsg(), pktcobj::ctype, cops_gate::deltimer, free, GATE_ALLOC_FAILED, GATE_ALLOCATED, GATE_CLOSED, GATE_CLOSED_ERR, GATE_DEL, GATE_DELETED, GATE_INFO, GATE_OPEN, cops_gate::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().

{
   int res, nfds, len;
   struct copsmsg *recmsg, *sendmsg;
   struct copsmsg recmsgb, sendmsgb;
   struct pollfd *pfds = NULL, *tmp;
   struct pktcobj *pobject;
   struct cops_cmts *cmts;
   struct cops_gate *gate;
   char *sobjp;
   uint16_t snst, sobjlen, scommand, recvtrid, actcount, reason, subreason;
   uint32_t gateid, subscrid, pktcerror;
   time_t last_exec = 0;

   recmsg = &recmsgb;
   sendmsg = &sendmsgb;

   ast_debug(3, "COPS: thread started\n");

   for (;;) {
      ast_free(pfds);
      pfds = NULL;
      nfds = 0;
      AST_LIST_LOCK(&cmts_list);
      AST_LIST_TRAVERSE(&cmts_list, cmts, list) {
         if (last_exec != time(NULL)) {
            if (cmts->state == 2 && cmts->katimer + cmts->keepalive < time(NULL)) {
               ast_log(LOG_WARNING, "KA timer (%is) expired cmts: %s\n",  cmts->keepalive, cmts->name);
               cmts->state = 0;
               cmts->katimer = -1;
               close(cmts->sfd);
               cmts->sfd = -1;
            }
         }
         if (cmts->sfd > 0) {
            if (!(tmp = ast_realloc(pfds, (nfds + 1) * sizeof(*pfds)))) {
               continue;
            }
            pfds = tmp;
            pfds[nfds].fd = cmts->sfd;
            pfds[nfds].events = POLLIN;
            pfds[nfds].revents = 0;
            nfds++;
         } else {
            cmts->sfd = cops_connect(cmts->host, cmts->port);
            if (cmts->sfd > 0) {
               cmts->state = 1;
               if (cmts->sfd > 0) {
                  if (!(tmp = ast_realloc(pfds, (nfds + 1) * sizeof(*pfds)))) {
                     continue;
                  }
                  pfds = tmp;
                  pfds[nfds].fd = cmts->sfd;
                  pfds[nfds].events = POLLIN;
                  pfds[nfds].revents = 0;
                  nfds++;
               }
            }
         }
      }
      AST_LIST_UNLOCK(&cmts_list);

      if (last_exec != time(NULL)) {
         last_exec = time(NULL);
         AST_LIST_LOCK(&gate_list);
         AST_LIST_TRAVERSE_SAFE_BEGIN(&gate_list, gate, list) {
            if (gate) {
               if (gate->deltimer && gate->deltimer < time(NULL)) {
                  gate->deltimer = time(NULL) + 5;
                  gate->trid = cops_trid++;
                  cops_gate_cmd(GATE_DEL, gate->cmts, gate->trid, 0, 0, 0, 0, 0, 0, gate);
                  ast_debug(3, "COPS: requested Gate-Del: CMTS: %s gateid: 0x%x\n", (gate->cmts) ? gate->cmts->name : "null", gate->gateid);
               }
               if (time(NULL) - gate->checked > gatetimeout) {
                  ast_debug(3, "COPS: remove from list GATE, CMTS: %s gateid: 0x%x\n", (gate->cmts) ? gate->cmts->name : "null", gate->gateid);
                  gate->state = GATE_TIMEOUT;
                  PKTCCOPS_DESTROY_CURRENT_GATE;
               } else if (time(NULL) - gate->checked > gateinfoperiod && (gate->state == GATE_ALLOCATED || gate->state == GATE_OPEN)) {
                  if (gate->cmts && (!gate->in_transaction || ( gate->in_transaction + 5 ) < time(NULL))) {
                     gate->trid = cops_trid++;
                     ast_debug(3, "COPS: Gate-Info send to CMTS: %s gateid: 0x%x\n", gate->cmts->name, gate->gateid);
                     cops_gate_cmd(GATE_INFO, gate->cmts, gate->trid, gate->mta, 0, 0, 0, 0, 0, gate);
                  }
               }
            }
         }
         AST_LIST_TRAVERSE_SAFE_END;
         AST_LIST_UNLOCK(&gate_list);
      }

      if (pktcreload == 2) {
         pktcreload = 0;
      }
      if ((res = ast_poll(pfds, nfds, 1000))) {
         AST_LIST_LOCK(&cmts_list);
         AST_LIST_TRAVERSE(&cmts_list, cmts, list) {
            int idx;
            if ((idx = ast_poll_fd_index(pfds, nfds, cmts->sfd)) > -1 && (pfds[idx].revents & POLLIN)) {
               len = cops_getmsg(cmts->sfd, recmsg);
               if (len > 0) {
                  ast_debug(3, "COPS: got from %s:\n Header: versflag=0x%.2x opcode=%i clienttype=0x%.4x msglength=%i\n",
                     cmts->name, recmsg->verflag, recmsg->opcode, recmsg->clienttype, recmsg->length);
                  if (recmsg->object != NULL) {
                     pobject = recmsg->object;
                     while (pobject != NULL) {
                        ast_debug(3, " OBJECT: length=%i cnum=%i ctype=%i\n", pobject->length, pobject->cnum, pobject->ctype);
                        if (recmsg->opcode == 1 && pobject->cnum == 1 && pobject->ctype == 1 ) {
                           cmts->handle = ntohl(*((uint32_t *) pobject->contents));
                           ast_debug(3, "    REQ client handle: %i\n", cmts->handle);
                           cmts->state = 2;
                           cmts->katimer = time(NULL);
                        } else if (pobject->cnum == 9 && pobject->ctype == 1) {
                           sobjp = pobject->contents;
                           subscrid = 0;
                           recvtrid = 0;
                           scommand = 0;
                           pktcerror = 0;
                           actcount = 0;
                           gateid = 0;
                           reason = 0;
                           subreason = 0;
                           while (sobjp < (pobject->contents + pobject->length - 4)) {
                              sobjlen = ntohs(*((uint16_t *) sobjp));
                              snst = ntohs(*((uint16_t *) (sobjp + 2)));
                              ast_debug(3, "   S-Num S-type: 0x%.4x len: %i\n", snst, sobjlen);
                              if (snst == 0x0101 ) {
                                 recvtrid = ntohs(*((uint16_t *) (sobjp + 4)));
                                 scommand = ntohs(*((uint16_t *) (sobjp + 6)));              
                                 ast_debug(3, "     Transaction Identifier command: %i trid %i\n", scommand, recvtrid);
                              } else if (snst == 0x0201) {
                                 subscrid = ntohl(*((uint32_t *) (sobjp + 4)));
                                 ast_debug(3, "     Subscriber ID: 0x%.8x\n", subscrid);
                              } else if (snst == 0x0301) {
                                 gateid = ntohl(*((uint32_t *) (sobjp + 4)));
                                 ast_debug(3, "      Gate ID: 0x%x 0x%.8x\n", gateid, gateid);
                              } else if (snst == 0x0401) {
                                 actcount = ntohs(*((uint16_t *) (sobjp + 6)));
                                 ast_debug(3, "      Activity Count: %i\n", actcount);
                              } else if (snst == 0x0901) {
                                 pktcerror = ntohl(*((uint32_t *) (sobjp + 4)));
                                 ast_debug(3, "      PKTC Error: 0x%.8x\n", pktcerror);
                              } else if (snst == 0x0d01) {
                                 reason = ntohs(*((uint16_t *) (sobjp + 4)));
                                 subreason = ntohs(*((uint16_t *) (sobjp + 6)));
                                 ast_debug(3, "      Reason: %u Subreason: %u\n", reason, subreason);
                              }
                              sobjp += sobjlen;
                              if (!sobjlen)
                                 break;
                           }
                           if (scommand == PKTCCOPS_SCOMMAND_GATE_CLOSE || scommand == PKTCCOPS_SCOMMAND_GATE_OPEN) {
                              AST_LIST_LOCK(&gate_list);
                              AST_LIST_TRAVERSE_SAFE_BEGIN(&gate_list, gate, list) {
                                 if (gate->cmts == cmts && gate->gateid == gateid) {
                                    if (scommand == PKTCCOPS_SCOMMAND_GATE_CLOSE && gate->state != GATE_CLOSED && gate->state != GATE_CLOSED_ERR ) {
                                       ast_debug(3, "COPS Gate Close Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name);
                                       if (subreason) {
                                          gate->state = GATE_CLOSED_ERR;
                                          PKTCCOPS_DESTROY_CURRENT_GATE;
                                       } else {
                                          gate->state = GATE_CLOSED;
                                          PKTCCOPS_DESTROY_CURRENT_GATE;
                                       }
                                       break;
                                    } else if (scommand == PKTCCOPS_SCOMMAND_GATE_OPEN && gate->state == GATE_ALLOCATED) {
                                       ast_debug(3, "COPS Gate Open Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name);
                                       gate->state = GATE_OPEN;
                                       if (gate->gate_open) {
                                          ast_debug(3, "Calling GATE-OPEN callback function\n");
                                          gate->gate_open(gate);
                                          gate->gate_open = NULL;
                                       }
                                       break;
                                    } 
                                 }
                              }
                              AST_LIST_TRAVERSE_SAFE_END;
                              AST_LIST_UNLOCK(&gate_list);
                           } 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) {
                              AST_LIST_LOCK(&gate_list);
                              AST_LIST_TRAVERSE_SAFE_BEGIN(&gate_list, gate, list) {
                                 if (gate->cmts == cmts && gate->trid == recvtrid) {
                                    gate->gateid = gateid;
                                    gate->checked = time(NULL);
                                    if (scommand == PKTCCOPS_SCOMMAND_GATE_SET_ACK) {
                                       ast_debug(3, "COPS Gate Set Ack Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name);
                                       gate->state = GATE_ALLOCATED;
                                       if (gate->got_dq_gi) {
                                          gate->got_dq_gi(gate);
                                          gate->got_dq_gi = NULL;
                                       }
                                    } else if (scommand == PKTCCOPS_SCOMMAND_GATE_SET_ERR) {
                                       ast_debug(3, "COPS Gate Set Error TrId: %i ErrorCode: 0x%.8x CMTS: %s\n ", recvtrid, pktcerror, cmts->name);
                                       gate->state = GATE_ALLOC_FAILED;
                                       if (gate->got_dq_gi) {
                                          gate->got_dq_gi(gate);
                                          gate->got_dq_gi = NULL;
                                       }
                                       PKTCCOPS_DESTROY_CURRENT_GATE;
                                    } else if (scommand == PKTCCOPS_SCOMMAND_GATE_INFO_ACK) {
                                       ast_debug(3, "COPS Gate Info Ack Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name);
                                    } else if (scommand == PKTCCOPS_SCOMMAND_GATE_INFO_ERR) {
                                       ast_debug(3, "COPS Gate Info Error Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name);
                                       gate->state = GATE_ALLOC_FAILED;
                                       PKTCCOPS_DESTROY_CURRENT_GATE;
                                    } else if (scommand == PKTCCOPS_SCOMMAND_GATE_DELETE_ACK) {
                                       ast_debug(3, "COPS Gate Deleted Gate ID: 0x%x TrId: %i CMTS: %s\n", gateid, recvtrid, cmts->name);
                                       gate->state = GATE_DELETED;
                                       PKTCCOPS_DESTROY_CURRENT_GATE;
                                    }
                                    gate->in_transaction = 0;
                                    break;
                                 }
                              }
                              AST_LIST_TRAVERSE_SAFE_END;
                              AST_LIST_UNLOCK(&gate_list);
                           }
                        }
                        pobject = pobject->next;
                     }
                  }

                  if (recmsg->opcode == 6 && recmsg->object && recmsg->object->cnum == 11 && recmsg->object->ctype == 1) {
                     ast_debug(3, "COPS: Client open %s\n", cmts->name);
                     sendmsg->msg = NULL;
                     sendmsg->verflag = 0x10;
                     sendmsg->opcode = 7; /* Client Accept */
                     sendmsg->clienttype = 0x8008; /* =PacketCable */
                     sendmsg->length = COPS_HEADER_SIZE + COPS_OBJECT_HEADER_SIZE + 4;
                     sendmsg->object = malloc(sizeof(struct pktcobj));
                     sendmsg->object->length = 4 + COPS_OBJECT_HEADER_SIZE;
                     sendmsg->object->cnum = 10; /* keppalive timer*/
                     sendmsg->object->ctype = 1;
                     sendmsg->object->contents = malloc(sizeof(uint32_t));
                     *((uint32_t *) sendmsg->object->contents) = htonl(cmts->keepalive & 0x0000ffff);
                     sendmsg->object->next = NULL;
                     cops_sendmsg(cmts->sfd, sendmsg);
                     cops_freemsg(sendmsg);
                  } else if (recmsg->opcode == 9) {
                     ast_debug(3, "COPS: Keepalive Request got echoing back %s\n", cmts->name);
                     cops_sendmsg(cmts->sfd, recmsg);
                     cmts->state = 2;
                     cmts->katimer = time(NULL);
                  }
               } 
               if (len <= 0) {
                  ast_debug(3, "COPS: lost connection to %s\n", cmts->name);
                  close(cmts->sfd);
                  cmts->sfd = -1;
                  cmts->state = 0;
               }
               cops_freemsg(recmsg);
            }
         }
         AST_LIST_UNLOCK(&cmts_list);        
      }
      if (pktcreload) {
         ast_debug(3, "Reloading pktccops...\n");
         AST_LIST_LOCK(&gate_list);
         AST_LIST_LOCK(&cmts_list);
         pktccops_unregister_ippools();
         AST_LIST_TRAVERSE(&cmts_list, cmts, list) {
            cmts->need_delete = 1;
         }
         load_pktccops_config();
         AST_LIST_TRAVERSE_SAFE_BEGIN(&cmts_list, cmts, list) {
            if (cmts && cmts->need_delete) {
               AST_LIST_TRAVERSE(&gate_list, gate, list) {
                  if (gate->cmts == cmts) {
                     ast_debug(3, "Null gate %s\n", gate->cmts->name);
                     gate->cmts = NULL;
                  }
                  gate->in_transaction = 0;
               }
               AST_LIST_UNLOCK(&gate_list);
               ast_debug(3, "removing cmts: %s\n", cmts->name);
               if (cmts->sfd > 0) {
                  close(cmts->sfd);
               }
               AST_LIST_REMOVE_CURRENT(list);
               free(cmts);
            }
         }
         AST_LIST_TRAVERSE_SAFE_END;
         AST_LIST_UNLOCK(&cmts_list);
         AST_LIST_UNLOCK(&gate_list);
         pktcreload = 2;
      }
      pthread_testcancel();
   }
   return NULL;
}
static uint32_t ftoieeef ( float  n) [static]

Definition at line 176 of file res_pktccops.c.

Referenced by cops_construct_gate().

{
   uint32_t res;
   memcpy(&res, &n, 4);
   return htonl(res);
}
static int load_module ( void  ) [static]
static int load_pktccops_config ( void  ) [static]

Definition at line 1023 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, ast_variable::name, cops_cmts::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().

{
   static char *cfg = "res_pktccops.conf";
   struct ast_config *config;
   struct ast_variable *v;
   struct cops_cmts *cmts;
   struct cops_ippool *new_ippool;
   const char *host, *cat, *port;
   int sfd, update;
   int res = 0;
   uint16_t t1_temp, t7_temp, t8_temp;
   uint32_t keepalive_temp;
   unsigned int a,b,c,d,e,f,g,h;
   struct ast_flags config_flags = {0};

   if (!(config = ast_config_load(cfg, config_flags))) {
      ast_log(LOG_WARNING, "Unable to load config file res_pktccops.conf\n");
      return -1;
   }
   for (cat = ast_category_browse(config, NULL); cat; cat = ast_category_browse(config, cat)) {
      if (!strcmp(cat, "general")) {
         for (v = ast_variable_browse(config, cat); v; v = v->next) {
            if (!strcasecmp(v->name, "t1")) {
               t1 = atoi(v->value);
            } else if (!strcasecmp(v->name, "t7")) {
               t7 = atoi(v->value);
            } else if (!strcasecmp(v->name, "t8")) {
               t8 = atoi(v->value);
            } else if (!strcasecmp(v->name, "keepalive")) {
               keepalive = atoi(v->value);
            } else if (!strcasecmp(v->name, "gateinfoperiod")) {
               gateinfoperiod = atoi(v->value);
            } else if (!strcasecmp(v->name, "gatetimeout")) {
               gatetimeout = atoi(v->value);
            } else {
               ast_log(LOG_WARNING, "Unkown option %s in general section of res_ptkccops.conf\n", v->name);
            }
         }        
      } else {
         /* Defaults */
         host = NULL;
         port = NULL;
         sfd = 0;
         t1_temp = t1;
         t7_temp = t7;
         t8_temp = t8;
         keepalive_temp = keepalive;

         for (v = ast_variable_browse(config, cat); v; v = v->next) {
            if (!strcasecmp(v->name, "host")) {
               host = v->value;           
            } else if (!strcasecmp(v->name, "port")) {
               port = v->value;
            } else if (!strcasecmp(v->name, "t1")) {
               t1_temp = atoi(v->value);
            } else if (!strcasecmp(v->name, "t7")) {
               t7_temp = atoi(v->value);
            } else if (!strcasecmp(v->name, "t8")) {
               t8_temp = atoi(v->value);
            } else if (!strcasecmp(v->name, "keepalive")) {
               keepalive_temp = atoi(v->value);
            } else if (!strcasecmp(v->name, "pool")) {
               /* we weill parse it in 2nd round */
            } else {
               ast_log(LOG_WARNING, "Unkown option %s in res_ptkccops.conf\n", v->name);
            }
         }

         update = 0;
         AST_LIST_TRAVERSE(&cmts_list, cmts, list) {
            if (!strcmp(cmts->name, cat)) {
               update = 1;
               break;
            }

         }
         if (!update) {
            cmts = ast_calloc(1, sizeof(*cmts));
            if (!cmts) {
               res = -1;
               break;
            }
            AST_LIST_INSERT_HEAD(&cmts_list, cmts, list);
         }
         if (cat) {
            ast_copy_string(cmts->name, cat, sizeof(cmts->name));
         }
         if (host) {
            ast_copy_string(cmts->host, host, sizeof(cmts->host));
         }
         if (port) {
            ast_copy_string(cmts->port, port, sizeof(cmts->port));
         } else {
            ast_copy_string(cmts->port, DEFAULT_COPS_PORT, sizeof(cmts->port));
         }

         cmts->t1 = t1_temp;
         cmts->t7 = t7_temp;
         cmts->t8 = t8_temp;
         cmts->keepalive = keepalive_temp;
         if (!update) {
            cmts->state = 0;
            cmts->sfd = -1;
         }
         cmts->need_delete = 0;
         for (v = ast_variable_browse(config, cat); v; v = v->next) {
            /* parse ipppol when we have cmts ptr */
            if (!strcasecmp(v->name, "pool")) {
               if (sscanf(v->value, "%3u.%3u.%3u.%3u %3u.%3u.%3u.%3u", &a, &b, &c, &d, &e, &f, &g, &h) == 8) {
                  new_ippool = ast_calloc(1, sizeof(*new_ippool));
                  if (!new_ippool) {
                     res = -1;
                     break;
                  }
                  new_ippool->start = a << 24 | b << 16 | c << 8 | d;
                  new_ippool->stop = e << 24 | f << 16 | g << 8 | h;
                  new_ippool->cmts = cmts;
                  pktccops_add_ippool(new_ippool);
               } else {
                  ast_log(LOG_WARNING, "Invalid ip pool format in res_pktccops.conf\n");
               }
            }
         }
      }
   }
   ast_config_destroy(config);
   return res;
}
static int pktccops_add_ippool ( struct cops_ippool ippool) [static]

Definition at line 1423 of file res_pktccops.c.

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

Referenced by load_pktccops_config().

{
   if (ippool) {
      AST_LIST_LOCK(&ippool_list);
      AST_LIST_INSERT_HEAD(&ippool_list, ippool, list);
      AST_LIST_UNLOCK(&ippool_list);
      return 0;
   } else {
      ast_log(LOG_WARNING, "Attempted to register NULL ippool?\n");
      return -1;
   }
}
static char* pktccops_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1386 of file res_pktccops.c.

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

{
   switch (cmd) {
   case CLI_INIT:
      e->command = "pktccops set debug {on|off}";
      e->usage = 
         "Usage: pktccops set debug {on|off}\n"
         "  Turn on/off debuging\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   if (a->argc != e->args)
      return CLI_SHOWUSAGE;
   if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
      pktccopsdebug = 1;
      ast_cli(a->fd, "PktcCOPS Debugging Enabled\n");
   } else if (!strncasecmp(a->argv[e->args - 1], "off", 2)) {
      pktccopsdebug = 0;
      ast_cli(a->fd, "PktcCOPS Debugging Disabled\n");
   } else {
      return CLI_SHOWUSAGE;
   }
   return CLI_SUCCESS;

}
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.

{
   int found = 0;
   int trid;
   uint32_t gateid;
   struct cops_gate *gate;
   struct cops_cmts *cmts;

   switch (cmd) {
   case CLI_INIT:
      e->command = "pktccops gatedel";
      e->usage = 
         "Usage: pktccops gatedel <cmts> <gateid>\n"
         "       Send Gate-Del to cmts.\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   if (a->argc < 4)
      return CLI_SHOWUSAGE;

   AST_LIST_LOCK(&cmts_list);
   AST_LIST_TRAVERSE(&cmts_list, cmts, list) {
      if (!strcmp(cmts->name, a->argv[2])) {
         ast_cli(a->fd, "Found cmts: %s\n", cmts->name);
         found = 1;
         break;
      }
   }
   AST_LIST_UNLOCK(&cmts_list);
   
   if (!found)
      return CLI_SHOWUSAGE;

   trid = cops_trid++;
   if (!sscanf(a->argv[3], "%x", &gateid)) {
      ast_cli(a->fd, "bad gate specification (%s)\n", a->argv[3]);   
      return CLI_SHOWUSAGE;
   }

   found = 0;
   AST_LIST_LOCK(&gate_list);
   AST_LIST_TRAVERSE(&gate_list, gate, list) {
      if (gate->gateid == gateid && gate->cmts == cmts) {
         found = 1;
         break;
      }
   }
      
   if (!found) {
      ast_cli(a->fd, "gate not found: %s\n", a->argv[3]);
      return CLI_SHOWUSAGE;
   }

   AST_LIST_UNLOCK(&gate_list);
   cops_gate_cmd(GATE_DEL, cmts, trid, 0, 0, 0, 0, 0, 0, gate);
   return CLI_SUCCESS;
}
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.

{
   int foundcmts = 0;
   int trid;
   unsigned int an,bn,cn,dn;
   uint32_t mta, ssip;
   struct cops_cmts *cmts;
   struct cops_gate *gate;

   switch (cmd) {
   case CLI_INIT:
      e->command = "pktccops gateset";
      e->usage = 
         "Usage: pktccops gateset <cmts> <mta> <acctcount> <bitrate> <packet size> <switch ip> <switch port>\n"
         "       Send Gate-Set to cmts.\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   if (a->argc < 9)
      return CLI_SHOWUSAGE;

   if (!strncmp(a->argv[2], "null", sizeof(a->argv[2]))) {
      cmts = NULL;
   } else {
      AST_LIST_LOCK(&cmts_list);
      AST_LIST_TRAVERSE(&cmts_list, cmts, list) {
         if (!strcmp(cmts->name, a->argv[2])) {
            ast_cli(a->fd, "Found cmts: %s\n", cmts->name);
            foundcmts = 1;
            break;
         }
      }
      AST_LIST_UNLOCK(&cmts_list);
      if (!foundcmts) {
         ast_cli(a->fd, "CMTS not found: %s\n", a->argv[2]);
         return CLI_SHOWUSAGE;
      }
   }

   trid = cops_trid++;
   if (sscanf(a->argv[3], "%3u.%3u.%3u.%3u", &an, &bn, &cn, &dn) != 4) {
      ast_cli(a->fd, "MTA specification (%s) does not look like an ipaddr\n", a->argv[3]);
      return CLI_SHOWUSAGE;
   }
   mta = an << 24 | bn << 16 | cn << 8 | dn;

   if (sscanf(a->argv[7], "%3u.%3u.%3u.%3u", &an, &bn, &cn, &dn) != 4) {
      ast_cli(a->fd, "SSIP specification (%s) does not look like an ipaddr\n", a->argv[7]);
      return CLI_SHOWUSAGE;
   }
   ssip = an << 24 | bn << 16 | cn << 8 | dn;

   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);
   return CLI_SUCCESS;
}
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.

{
   struct cops_cmts *cmts;
   char statedesc[16];
   int katimer;
   
   switch(cmd) {
   case CLI_INIT:
      e->command = "pktccops show cmtses";
      e->usage = 
         "Usage: pktccops show cmtses\n"
         "       List PacketCable COPS CMTSes.\n";

      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   ast_cli(a->fd, "%-16s %-24s %-12s %7s\n", "Name        ", "Host                ", "Status    ", "KA timer  ");
   ast_cli(a->fd, "%-16s %-24s %-12s %7s\n", "------------", "--------------------", "----------", "-----------");
   AST_LIST_LOCK(&cmts_list);
   AST_LIST_TRAVERSE(&cmts_list, cmts, list) {
      katimer = -1;
      if (cmts->state == 2) {
         ast_copy_string(statedesc, "Connected", sizeof(statedesc));
         katimer = (int) (time(NULL) - cmts->katimer);
      } else if (cmts->state == 1) {
         ast_copy_string(statedesc, "Connecting", sizeof(statedesc));
      } else {
         ast_copy_string(statedesc, "N/A", sizeof(statedesc));
      }
      ast_cli(a->fd, "%-16s %-15s:%-8s %-12s %-7d\n", cmts->name, cmts->host, cmts->port, statedesc, katimer);
   }
   AST_LIST_UNLOCK(&cmts_list);
   return CLI_SUCCESS;
}
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.

{
   struct cops_gate *gate;
   char state_desc[16];

   switch(cmd) {
   case CLI_INIT:
      e->command = "pktccops show gates";
      e->usage = 
         "Usage: pktccops show gates\n"
         "       List PacketCable COPS GATEs.\n";

      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   ast_cli(a->fd, "%-16s %-12s %-12s %-10s %-10s %-10s\n" ,"CMTS", "Gate-Id","MTA", "Status", "AllocTime", "CheckTime");
   ast_cli(a->fd, "%-16s %-12s %-12s %-10s %-10s %-10s\n" ,"--------------" ,"----------", "----------", "--------", "--------", "--------\n");
   AST_LIST_LOCK(&cmts_list);
   AST_LIST_LOCK(&gate_list);
   AST_LIST_TRAVERSE(&gate_list, gate, list) {
      if (gate->state == GATE_ALLOC_FAILED) {
         ast_copy_string(state_desc, "Failed", sizeof(state_desc));
      } else if (gate->state == GATE_ALLOC_PROGRESS) {
         ast_copy_string(state_desc, "In Progress", sizeof(state_desc));
      } else if (gate->state == GATE_ALLOCATED) {
         ast_copy_string(state_desc, "Allocated", sizeof(state_desc));
      } else if (gate->state == GATE_CLOSED) {
         ast_copy_string(state_desc, "Closed", sizeof(state_desc));
      } else if (gate->state == GATE_CLOSED_ERR) {
         ast_copy_string(state_desc, "ClosedErr", sizeof(state_desc));
      } else if (gate->state == GATE_OPEN) {
         ast_copy_string(state_desc, "Open", sizeof(state_desc));
      } else if (gate->state == GATE_DELETED) {
         ast_copy_string(state_desc, "Deleted", sizeof(state_desc));
      } else {
         ast_copy_string(state_desc, "N/A", sizeof(state_desc));
      }
      
      ast_cli(a->fd, "%-16s 0x%.8x   0x%08x   %-10s %10i %10i %u\n", (gate->cmts) ? gate->cmts->name : "null" , gate->gateid, gate->mta, 
         state_desc, (int) (time(NULL) - gate->allocated), (gate->checked) ? (int) (time(NULL) - gate->checked) : 0, (unsigned int) gate->in_transaction);
   }
   AST_LIST_UNLOCK(&cmts_list);
   AST_LIST_UNLOCK(&gate_list);
   return CLI_SUCCESS;
}
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.

{
   struct cops_ippool *ippool;
   char start[32];
   char stop[32];

   switch(cmd) {
   case CLI_INIT:
      e->command = "pktccops show pools";
      e->usage = 
         "Usage: pktccops show pools\n"
         "       List PacketCable COPS ip pools of MTAs.\n";

      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   ast_cli(a->fd, "%-16s %-18s %-7s\n", "Start     ", "Stop      ", "CMTS    ");
   ast_cli(a->fd, "%-16s %-18s %-7s\n", "----------", "----------", "--------");
   AST_LIST_LOCK(&ippool_list);
   AST_LIST_TRAVERSE(&ippool_list, ippool, list) {
      snprintf(start, sizeof(start), "%3u.%3u.%3u.%3u", ippool->start >> 24, (ippool->start >> 16) & 0x000000ff, (ippool->start >> 8) & 0x000000ff, ippool->start & 0x000000ff);

      snprintf(stop, sizeof(stop), "%3u.%3u.%3u.%3u", ippool->stop >> 24, (ippool->stop >> 16) & 0x000000ff, (ippool->stop >> 8) & 0x000000ff, ippool->stop & 0x000000ff);
      ast_cli(a->fd, "%-16s %-18s %-16s\n", start, stop, ippool->cmts->name);
   }
   AST_LIST_UNLOCK(&ippool_list);
   return CLI_SUCCESS;
}
static void pktccops_unregister_cmtses ( void  ) [static]

Definition at line 1436 of file res_pktccops.c.

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

Referenced by unload_module().

{
   struct cops_cmts *cmts;
   struct cops_gate *gate;
   AST_LIST_LOCK(&cmts_list);
   while ((cmts = AST_LIST_REMOVE_HEAD(&cmts_list, list))) {
      if (cmts->sfd > 0) {
         close(cmts->sfd);
      }
      free(cmts);
   }
   AST_LIST_UNLOCK(&cmts_list);

   AST_LIST_LOCK(&gate_list);
   while ((gate = AST_LIST_REMOVE_HEAD(&gate_list, list))) {
      free(gate);
   }
   AST_LIST_UNLOCK(&gate_list);
}
static void pktccops_unregister_ippools ( void  ) [static]

Definition at line 1456 of file res_pktccops.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free.

Referenced by do_pktccops(), and unload_module().

{
   struct cops_ippool *ippool;
   AST_LIST_LOCK(&ippool_list);
   while ((ippool = AST_LIST_REMOVE_HEAD(&ippool_list, list))) {
      free(ippool);
   }
   AST_LIST_UNLOCK(&ippool_list);
}
static int reload_module ( void  ) [static]

Definition at line 1502 of file res_pktccops.c.

References ast_log(), LOG_NOTICE, and pktcreload.

{
   /* Prohibit unloading */
   if (pktcreload) {
      ast_log(LOG_NOTICE, "Previous reload in progress, please wait!\n");
      return -1;
   }
   pktcreload = 1;
   return 0;
}
static int restart_pktc_thread ( void  ) [static]

Definition at line 994 of file res_pktccops.c.

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

Referenced by load_module().

{
   if (pktccops_thread == AST_PTHREADT_STOP) {
      return 0;
   }
   if (ast_mutex_lock(&pktccops_lock)) {
      ast_log(LOG_WARNING, "Unable to lock pktccops\n");
      return -1;
   }
   if (pktccops_thread == pthread_self()) {
      ast_mutex_unlock(&pktccops_lock);
      ast_log(LOG_WARNING, "Cannot kill myself\n");
      return -1;
   }
   if (pktccops_thread != AST_PTHREADT_NULL) {
      /* Wake up the thread */
      pthread_kill(pktccops_thread, SIGURG);
   } else {
      /* Start a new monitor */
      if (ast_pthread_create_background(&pktccops_thread, NULL, do_pktccops, NULL) < 0) {
         ast_mutex_unlock(&pktccops_lock);
         ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
         return -1;
      }
   }
   ast_mutex_unlock(&pktccops_lock);
   return 0;
}

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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload_module, } [static]

Definition at line 1517 of file res_pktccops.c.

Definition at line 1517 of file res_pktccops.c.

struct ast_cli_entry cli_pktccops[] [static]

Definition at line 1414 of file res_pktccops.c.

uint16_t cops_trid = 0 [static]

Definition at line 91 of file res_pktccops.c.

int gateinfoperiod = 60 [static]

Definition at line 164 of file res_pktccops.c.

Referenced by do_pktccops(), and load_pktccops_config().

int gatetimeout = 150 [static]

Definition at line 165 of file res_pktccops.c.

Referenced by do_pktccops(), and load_pktccops_config().

uint32_t keepalive = 60 [static]

Definition at line 161 of file res_pktccops.c.

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

Definition at line 89 of file res_pktccops.c.

Referenced by restart_pktc_thread(), and unload_module().

pthread_t pktccops_thread = AST_PTHREADT_NULL [static]

Definition at line 90 of file res_pktccops.c.

int pktccopsdebug = 0 [static]

Definition at line 162 of file res_pktccops.c.

Referenced by cops_gate_cmd(), and pktccops_debug().

int pktcreload = 0 [static]

Definition at line 163 of file res_pktccops.c.

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

uint16_t t1 = 250 [static]

Definition at line 158 of file res_pktccops.c.

Referenced by create_match_char_tree(), dahdi_bridge(), differ_by_repeat(), and is_prefix().

uint16_t t7 = 200 [static]

Definition at line 159 of file res_pktccops.c.

uint16_t t8 = 300 [static]

Definition at line 160 of file res_pktccops.c.