Mon May 14 04:49:43 2007

Asterisk developer's documentation


iax2-parser.h File Reference

Implementation of the IAX2 protocol. More...

#include "asterisk/linkedlists.h"

Include dependency graph for iax2-parser.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  iax_frame
struct  iax_ie_data
struct  iax_ies

Defines

#define DIRECTION_INGRESS   1
#define DIRECTION_OUTGRESS   2

Functions

void iax_frame_free (struct iax_frame *fr)
iax_frameiax_frame_new (int direction, int datalen, unsigned int cacheable)
void iax_frame_wrap (struct iax_frame *fr, struct ast_frame *f)
int iax_get_frames (void)
int iax_get_iframes (void)
int iax_get_oframes (void)
const char * iax_ie2str (int ie)
int iax_ie_append (struct iax_ie_data *ied, unsigned char ie)
int iax_ie_append_addr (struct iax_ie_data *ied, unsigned char ie, const struct sockaddr_in *sin)
int iax_ie_append_byte (struct iax_ie_data *ied, unsigned char ie, unsigned char dat)
int iax_ie_append_int (struct iax_ie_data *ied, unsigned char ie, unsigned int value)
int iax_ie_append_raw (struct iax_ie_data *ied, unsigned char ie, const void *data, int datalen)
int iax_ie_append_short (struct iax_ie_data *ied, unsigned char ie, unsigned short value)
int iax_ie_append_str (struct iax_ie_data *ied, unsigned char ie, const char *str)
int iax_parse_ies (struct iax_ies *ies, unsigned char *data, int datalen)
void iax_set_error (void(*output)(const char *data))
void iax_set_output (void(*output)(const char *data))
void iax_showframe (struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)


Detailed Description

Implementation of the IAX2 protocol.

Definition in file iax2-parser.h.


Define Documentation

#define DIRECTION_INGRESS   1

Definition at line 79 of file iax2-parser.h.

Referenced by iax_frame_free(), iax_frame_new(), and iaxfrdup2().

#define DIRECTION_OUTGRESS   2

Definition at line 80 of file iax2-parser.h.

Referenced by iax2_send(), iax_frame_free(), and send_trunk().


Function Documentation

void iax_frame_free ( struct iax_frame fr  ) 

Definition at line 1003 of file iax2-parser.c.

References AST_LIST_INSERT_HEAD, iax_frame::cacheable, iax_frame::direction, DIRECTION_INGRESS, DIRECTION_OUTGRESS, errorf, and free.

Referenced by iax2_frame_free(), and network_thread().

01004 {
01005 #if !defined(LOW_MEMORY)
01006    struct iax_frames *iax_frames;
01007 #endif
01008 
01009    /* Note: does not remove from scheduler! */
01010    if (fr->direction == DIRECTION_INGRESS)
01011       ast_atomic_fetchadd_int(&iframes, -1);
01012    else if (fr->direction == DIRECTION_OUTGRESS)
01013       ast_atomic_fetchadd_int(&oframes, -1);
01014    else {
01015       errorf("Attempt to double free frame detected\n");
01016       return;
01017    }
01018    ast_atomic_fetchadd_int(&frames, -1);
01019 
01020 #if !defined(LOW_MEMORY)
01021    if (!fr->cacheable || !(iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
01022       free(fr);
01023       return;
01024    }
01025 
01026    fr->direction = 0;
01027    AST_LIST_INSERT_HEAD(iax_frames, fr, list);
01028 #else
01029    free(fr);
01030 #endif
01031 }

struct iax_frame* iax_frame_new ( int  direction,
int  datalen,
unsigned int  cacheable 
)

Definition at line 957 of file iax2-parser.c.

References ast_calloc, ast_calloc_cache, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, DIRECTION_INGRESS, and iax_frame::mallocd_datalen.

Referenced by iax2_send(), and iaxfrdup2().

00958 {
00959    struct iax_frame *fr = NULL;
00960 
00961 #if !defined(LOW_MEMORY)
00962    struct iax_frames *iax_frames;
00963 
00964    /* Attempt to get a frame from this thread's cache */
00965    if ((iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
00966       AST_LIST_TRAVERSE_SAFE_BEGIN(iax_frames, fr, list) {
00967          if (fr->mallocd_datalen >= datalen) {
00968             size_t mallocd_datalen = fr->mallocd_datalen;
00969             AST_LIST_REMOVE_CURRENT(iax_frames, list);
00970             memset(fr, 0, sizeof(*fr));
00971             fr->mallocd_datalen = mallocd_datalen;
00972             break;
00973          }
00974       }
00975       AST_LIST_TRAVERSE_SAFE_END
00976    }
00977    if (!fr) {
00978       if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen)))
00979          return NULL;
00980       fr->mallocd_datalen = datalen;
00981    }
00982 #else
00983    if (!(fr = ast_calloc(1, sizeof(*fr) + datalen)))
00984       return NULL;
00985    fr->mallocd_datalen = datalen;
00986 #endif
00987 
00988 
00989    fr->direction = direction;
00990    fr->retrans = -1;
00991    fr->cacheable = cacheable;
00992    
00993    if (fr->direction == DIRECTION_INGRESS)
00994       ast_atomic_fetchadd_int(&iframes, 1);
00995    else
00996       ast_atomic_fetchadd_int(&oframes, 1);
00997    
00998    ast_atomic_fetchadd_int(&frames, 1);
00999 
01000    return fr;
01001 }

void iax_frame_wrap ( struct iax_frame fr,
struct ast_frame f 
)

Definition at line 933 of file iax2-parser.c.

References iax_frame::af, iax_frame::afdata, AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_swapcopy_samples(), ast_frame::data, ast_frame::datalen, ast_frame::delivery, f, ast_frame::frametype, ast_frame::len, ast_frame::mallocd, ast_frame::offset, ast_frame::samples, ast_frame::src, and ast_frame::subclass.

Referenced by iax2_send(), iaxfrdup2(), and socket_process().

00934 {
00935    fr->af.frametype = f->frametype;
00936    fr->af.subclass = f->subclass;
00937    fr->af.mallocd = 0;           /* Our frame is static relative to the container */
00938    fr->af.datalen = f->datalen;
00939    fr->af.samples = f->samples;
00940    fr->af.offset = AST_FRIENDLY_OFFSET;
00941    fr->af.src = f->src;
00942    fr->af.delivery.tv_sec = 0;
00943    fr->af.delivery.tv_usec = 0;
00944    fr->af.data = fr->afdata;
00945    fr->af.len = f->len;
00946    if (fr->af.datalen) {
00947 #if __BYTE_ORDER == __LITTLE_ENDIAN
00948       /* We need to byte-swap slinear samples from network byte order */
00949       if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass == AST_FORMAT_SLINEAR)) {
00950          ast_swapcopy_samples(fr->af.data, f->data, fr->af.samples);
00951       } else
00952 #endif
00953       memcpy(fr->af.data, f->data, fr->af.datalen);
00954    }
00955 }

int iax_get_frames ( void   ) 

Definition at line 1046 of file iax2-parser.c.

Referenced by iax2_show_stats().

01046 { return frames; }

int iax_get_iframes ( void   ) 

Definition at line 1047 of file iax2-parser.c.

Referenced by iax2_show_stats().

01047 { return iframes; }

int iax_get_oframes ( void   ) 

Definition at line 1048 of file iax2-parser.c.

Referenced by iax2_show_stats().

01048 { return oframes; }

const char* iax_ie2str ( int  ie  ) 

Definition at line 289 of file iax2-parser.c.

References ies, and name.

Referenced by iax_ie_append_raw(), and iax_parse_ies().

00290 {
00291    int x;
00292    for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
00293       if (ies[x].ie == ie)
00294          return ies[x].name;
00295    }
00296    return "Unknown IE";
00297 }

int iax_ie_append ( struct iax_ie_data ied,
unsigned char  ie 
)

Definition at line 598 of file iax2-parser.c.

References iax_ie_append_raw().

Referenced by iax2_call(), and iax_firmware_append().

00599 {
00600    return iax_ie_append_raw(ied, ie, NULL, 0);
00601 }

int iax_ie_append_addr ( struct iax_ie_data ied,
unsigned char  ie,
const struct sockaddr_in *  sin 
)

Definition at line 569 of file iax2-parser.c.

References iax_ie_append_raw().

Referenced by iax2_start_transfer(), and update_registry().

00570 {
00571    return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in));
00572 }

int iax_ie_append_byte ( struct iax_ie_data ied,
unsigned char  ie,
unsigned char  dat 
)

Definition at line 593 of file iax2-parser.c.

References iax_ie_append_raw().

Referenced by __auth_reject(), __auto_hangup(), authenticate_request(), iax2_call(), iax2_hangup(), iax_provision_build(), and socket_process().

00594 {
00595    return iax_ie_append_raw(ied, ie, &dat, 1);
00596 }

int iax_ie_append_int ( struct iax_ie_data ied,
unsigned char  ie,
unsigned int  value 
)

Definition at line 574 of file iax2-parser.c.

References iax_ie_append_raw().

Referenced by cache_get_callno_locked(), construct_rr(), iax2_call(), iax2_start_transfer(), iax_firmware_append(), iax_provision_build(), socket_process(), try_transfer(), and update_registry().

00575 {
00576    unsigned int newval;
00577    newval = htonl(value);
00578    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00579 }

int iax_ie_append_raw ( struct iax_ie_data ied,
unsigned char  ie,
const void *  data,
int  datalen 
)

Definition at line 554 of file iax2-parser.c.

References iax_ie_data::buf, errorf, iax_ie2str(), and iax_ie_data::pos.

Referenced by iax2_provision(), iax_firmware_append(), iax_ie_append(), iax_ie_append_addr(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), and iax_ie_append_str().

00555 {
00556    char tmp[256];
00557    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00558       snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", iax_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
00559       errorf(tmp);
00560       return -1;
00561    }
00562    ied->buf[ied->pos++] = ie;
00563    ied->buf[ied->pos++] = datalen;
00564    memcpy(ied->buf + ied->pos, data, datalen);
00565    ied->pos += datalen;
00566    return 0;
00567 }

int iax_ie_append_short ( struct iax_ie_data ied,
unsigned char  ie,
unsigned short  value 
)

Definition at line 581 of file iax2-parser.c.

References iax_ie_append_raw().

Referenced by authenticate_request(), cache_get_callno_locked(), construct_rr(), dp_lookup(), iax2_call(), iax2_do_register(), iax2_start_transfer(), iax_provision_build(), registry_authrequest(), registry_rerequest(), socket_process(), and update_registry().

00582 {
00583    unsigned short newval;
00584    newval = htons(value);
00585    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00586 }

int iax_ie_append_str ( struct iax_ie_data ied,
unsigned char  ie,
const char *  str 
)

Definition at line 588 of file iax2-parser.c.

References iax_ie_append_raw().

Referenced by __auth_reject(), __auto_hangup(), authenticate(), authenticate_request(), cache_get_callno_locked(), dp_lookup(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_transfer(), iax_provision_build(), registry_authrequest(), registry_rerequest(), socket_process(), and update_registry().

00589 {
00590    return iax_ie_append_raw(ied, ie, str, strlen(str));
00591 }

int iax_parse_ies ( struct iax_ies ies,
unsigned char *  data,
int  datalen 
)

Definition at line 613 of file iax2-parser.c.

References ast_variable_new(), errorf, get_unaligned_uint16(), get_unaligned_uint32(), iax_ie2str(), IAX_IE_ADSICPE, IAX_IE_APPARENT_ADDR, IAX_IE_AUTHMETHODS, IAX_IE_AUTOANSWER, IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CALLING_ANI, IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_CALLINGPRES, IAX_IE_CALLINGTNS, IAX_IE_CALLINGTON, IAX_IE_CALLNO, IAX_IE_CAPABILITY, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_CHALLENGE, IAX_IE_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DEVICETYPE, IAX_IE_DNID, IAX_IE_DPSTATUS, IAX_IE_ENCKEY, IAX_IE_ENCRYPTION, IAX_IE_FIRMWAREVER, IAX_IE_FORMAT, IAX_IE_FWBLOCKDATA, IAX_IE_FWBLOCKDESC, IAX_IE_IAX_UNKNOWN, IAX_IE_LANGUAGE, IAX_IE_MD5_RESULT, IAX_IE_MSGCOUNT, IAX_IE_MUSICONHOLD, IAX_IE_PASSWORD, IAX_IE_PROVVER, IAX_IE_RDNIS, IAX_IE_REFRESH, IAX_IE_RR_DELAY, IAX_IE_RR_DROPPED, IAX_IE_RR_JITTER, IAX_IE_RR_LOSS, IAX_IE_RR_OOO, IAX_IE_RR_PKTS, IAX_IE_RSA_RESULT, IAX_IE_SAMPLINGRATE, IAX_IE_SERVICEIDENT, IAX_IE_TRANSFERID, IAX_IE_USERNAME, IAX_IE_VARIABLE, IAX_IE_VERSION, IAX_RATE_8KHZ, ies, len, outputf, and var.

Referenced by socket_process().

00614 {
00615    /* Parse data into information elements */
00616    int len;
00617    int ie;
00618    char tmp[256], *tmp2;
00619    struct ast_variable *var;
00620    memset(ies, 0, (int)sizeof(struct iax_ies));
00621    ies->msgcount = -1;
00622    ies->firmwarever = -1;
00623    ies->calling_ton = -1;
00624    ies->calling_tns = -1;
00625    ies->calling_pres = -1;
00626    ies->samprate = IAX_RATE_8KHZ;
00627    while(datalen >= 2) {
00628       ie = data[0];
00629       len = data[1];
00630       if (len > datalen - 2) {
00631          errorf("Information element length exceeds message size\n");
00632          return -1;
00633       }
00634       switch(ie) {
00635       case IAX_IE_CALLED_NUMBER:
00636          ies->called_number = (char *)data + 2;
00637          break;
00638       case IAX_IE_CALLING_NUMBER:
00639          ies->calling_number = (char *)data + 2;
00640          break;
00641       case IAX_IE_CALLING_ANI:
00642          ies->calling_ani = (char *)data + 2;
00643          break;
00644       case IAX_IE_CALLING_NAME:
00645          ies->calling_name = (char *)data + 2;
00646          break;
00647       case IAX_IE_CALLED_CONTEXT:
00648          ies->called_context = (char *)data + 2;
00649          break;
00650       case IAX_IE_USERNAME:
00651          ies->username = (char *)data + 2;
00652          break;
00653       case IAX_IE_PASSWORD:
00654          ies->password = (char *)data + 2;
00655          break;
00656       case IAX_IE_CODEC_PREFS:
00657          ies->codec_prefs = (char *)data + 2;
00658          break;
00659       case IAX_IE_CAPABILITY:
00660          if (len != (int)sizeof(unsigned int)) {
00661             snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00662             errorf(tmp);
00663          } else
00664             ies->capability = ntohl(get_unaligned_uint32(data + 2));
00665          break;
00666       case IAX_IE_FORMAT:
00667          if (len != (int)sizeof(unsigned int)) {
00668             snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00669             errorf(tmp);
00670          } else
00671             ies->format = ntohl(get_unaligned_uint32(data + 2));
00672          break;
00673       case IAX_IE_LANGUAGE:
00674          ies->language = (char *)data + 2;
00675          break;
00676       case IAX_IE_VERSION:
00677          if (len != (int)sizeof(unsigned short)) {
00678             snprintf(tmp, (int)sizeof(tmp),  "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00679             errorf(tmp);
00680          } else
00681             ies->version = ntohs(get_unaligned_uint16(data + 2));
00682          break;
00683       case IAX_IE_ADSICPE:
00684          if (len != (int)sizeof(unsigned short)) {
00685             snprintf(tmp, (int)sizeof(tmp), "Expecting adsicpe to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00686             errorf(tmp);
00687          } else
00688             ies->adsicpe = ntohs(get_unaligned_uint16(data + 2));
00689          break;
00690       case IAX_IE_SAMPLINGRATE:
00691          if (len != (int)sizeof(unsigned short)) {
00692             snprintf(tmp, (int)sizeof(tmp), "Expecting samplingrate to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00693             errorf(tmp);
00694          } else
00695             ies->samprate = ntohs(get_unaligned_uint16(data + 2));
00696          break;
00697       case IAX_IE_DNID:
00698          ies->dnid = (char *)data + 2;
00699          break;
00700       case IAX_IE_RDNIS:
00701          ies->rdnis = (char *)data + 2;
00702          break;
00703       case IAX_IE_AUTHMETHODS:
00704          if (len != (int)sizeof(unsigned short))  {
00705             snprintf(tmp, (int)sizeof(tmp), "Expecting authmethods to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00706             errorf(tmp);
00707          } else
00708             ies->authmethods = ntohs(get_unaligned_uint16(data + 2));
00709          break;
00710       case IAX_IE_ENCRYPTION:
00711          if (len != (int)sizeof(unsigned short))  {
00712             snprintf(tmp, (int)sizeof(tmp), "Expecting encryption to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00713             errorf(tmp);
00714          } else
00715             ies->encmethods = ntohs(get_unaligned_uint16(data + 2));
00716          break;
00717       case IAX_IE_CHALLENGE:
00718          ies->challenge = (char *)data + 2;
00719          break;
00720       case IAX_IE_MD5_RESULT:
00721          ies->md5_result = (char *)data + 2;
00722          break;
00723       case IAX_IE_RSA_RESULT:
00724          ies->rsa_result = (char *)data + 2;
00725          break;
00726       case IAX_IE_APPARENT_ADDR:
00727          ies->apparent_addr = ((struct sockaddr_in *)(data + 2));
00728          break;
00729       case IAX_IE_REFRESH:
00730          if (len != (int)sizeof(unsigned short)) {
00731             snprintf(tmp, (int)sizeof(tmp),  "Expecting refresh to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00732             errorf(tmp);
00733          } else
00734             ies->refresh = ntohs(get_unaligned_uint16(data + 2));
00735          break;
00736       case IAX_IE_DPSTATUS:
00737          if (len != (int)sizeof(unsigned short)) {
00738             snprintf(tmp, (int)sizeof(tmp),  "Expecting dpstatus to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00739             errorf(tmp);
00740          } else
00741             ies->dpstatus = ntohs(get_unaligned_uint16(data + 2));
00742          break;
00743       case IAX_IE_CALLNO:
00744          if (len != (int)sizeof(unsigned short)) {
00745             snprintf(tmp, (int)sizeof(tmp),  "Expecting callno to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00746             errorf(tmp);
00747          } else
00748             ies->callno = ntohs(get_unaligned_uint16(data + 2));
00749          break;
00750       case IAX_IE_CAUSE:
00751          ies->cause = (char *)data + 2;
00752          break;
00753       case IAX_IE_CAUSECODE:
00754          if (len != 1) {
00755             snprintf(tmp, (int)sizeof(tmp), "Expecting causecode to be single byte but was %d\n", len);
00756             errorf(tmp);
00757          } else {
00758             ies->causecode = data[2];
00759          }
00760          break;
00761       case IAX_IE_IAX_UNKNOWN:
00762          if (len == 1)
00763             ies->iax_unknown = data[2];
00764          else {
00765             snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len);
00766             errorf(tmp);
00767          }
00768          break;
00769       case IAX_IE_MSGCOUNT:
00770          if (len != (int)sizeof(unsigned short)) {
00771             snprintf(tmp, (int)sizeof(tmp), "Expecting msgcount to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00772             errorf(tmp);
00773          } else
00774             ies->msgcount = ntohs(get_unaligned_uint16(data + 2));   
00775          break;
00776       case IAX_IE_AUTOANSWER:
00777          ies->autoanswer = 1;
00778          break;
00779       case IAX_IE_MUSICONHOLD:
00780          ies->musiconhold = 1;
00781          break;
00782       case IAX_IE_TRANSFERID:
00783          if (len != (int)sizeof(unsigned int)) {
00784             snprintf(tmp, (int)sizeof(tmp), "Expecting transferid to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00785             errorf(tmp);
00786          } else
00787             ies->transferid = ntohl(get_unaligned_uint32(data + 2));
00788          break;
00789       case IAX_IE_DATETIME:
00790          if (len != (int)sizeof(unsigned int)) {
00791             snprintf(tmp, (int)sizeof(tmp), "Expecting date/time to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00792             errorf(tmp);
00793          } else
00794             ies->datetime = ntohl(get_unaligned_uint32(data + 2));
00795          break;
00796       case IAX_IE_FIRMWAREVER:
00797          if (len != (int)sizeof(unsigned short)) {
00798             snprintf(tmp, (int)sizeof(tmp), "Expecting firmwarever to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00799             errorf(tmp);
00800          } else
00801             ies->firmwarever = ntohs(get_unaligned_uint16(data + 2));   
00802          break;
00803       case IAX_IE_DEVICETYPE:
00804          ies->devicetype = (char *)data + 2;
00805          break;
00806       case IAX_IE_SERVICEIDENT:
00807          ies->serviceident = (char *)data + 2;
00808          break;
00809       case IAX_IE_FWBLOCKDESC:
00810          if (len != (int)sizeof(unsigned int)) {
00811             snprintf(tmp, (int)sizeof(tmp), "Expected block desc to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00812             errorf(tmp);
00813          } else
00814             ies->fwdesc = ntohl(get_unaligned_uint32(data + 2));
00815          break;
00816       case IAX_IE_FWBLOCKDATA:
00817          ies->fwdata = data + 2;
00818          ies->fwdatalen = len;
00819          break;
00820       case IAX_IE_ENCKEY:
00821          ies->enckey = data + 2;
00822          ies->enckeylen = len;
00823          break;
00824       case IAX_IE_PROVVER:
00825          if (len != (int)sizeof(unsigned int)) {
00826             snprintf(tmp, (int)sizeof(tmp), "Expected provisioning version to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00827             errorf(tmp);
00828          } else {
00829             ies->provverpres = 1;
00830             ies->provver = ntohl(get_unaligned_uint32(data + 2));
00831          }
00832          break;
00833       case IAX_IE_CALLINGPRES:
00834          if (len == 1)
00835             ies->calling_pres = data[2];
00836          else {
00837             snprintf(tmp, (int)sizeof(tmp), "Expected single byte callingpres, but was %d long\n", len);
00838             errorf(tmp);
00839          }
00840          break;
00841       case IAX_IE_CALLINGTON:
00842          if (len == 1)
00843             ies->calling_ton = data[2];
00844          else {
00845             snprintf(tmp, (int)sizeof(tmp), "Expected single byte callington, but was %d long\n", len);
00846             errorf(tmp);
00847          }
00848          break;
00849       case IAX_IE_CALLINGTNS:
00850          if (len != (int)sizeof(unsigned short)) {
00851             snprintf(tmp, (int)sizeof(tmp), "Expecting callingtns to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00852             errorf(tmp);
00853          } else
00854             ies->calling_tns = ntohs(get_unaligned_uint16(data + 2));   
00855          break;
00856                case IAX_IE_RR_JITTER:
00857                        if (len != (int)sizeof(unsigned int)) {
00858                                snprintf(tmp, (int)sizeof(tmp), "Expected jitter rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00859                                errorf(tmp);
00860                        } else {
00861                                ies->rr_jitter = ntohl(get_unaligned_uint32(data + 2));
00862                        }
00863                        break;
00864                case IAX_IE_RR_LOSS:
00865                        if (len != (int)sizeof(unsigned int)) {
00866                                snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00867                                errorf(tmp);
00868                        } else {
00869                                ies->rr_loss = ntohl(get_unaligned_uint32(data + 2));
00870                        }
00871                        break;
00872                case IAX_IE_RR_PKTS:
00873                        if (len != (int)sizeof(unsigned int)) {
00874                                snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00875                                errorf(tmp);
00876                        } else {
00877                                ies->rr_pkts = ntohl(get_unaligned_uint32(data + 2));
00878                        }
00879                        break;
00880                case IAX_IE_RR_DELAY:
00881                        if (len != (int)sizeof(unsigned short)) {
00882                                snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00883                         errorf(tmp);
00884                        } else {
00885                                ies->rr_delay = ntohs(get_unaligned_uint16(data + 2));
00886                        }
00887                        break;
00888       case IAX_IE_RR_DROPPED:
00889          if (len != (int)sizeof(unsigned int)) {
00890             snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00891             errorf(tmp);
00892          } else {
00893             ies->rr_dropped = ntohl(get_unaligned_uint32(data + 2));
00894          }
00895          break;
00896       case IAX_IE_RR_OOO:
00897          if (len != (int)sizeof(unsigned int)) {
00898             snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00899             errorf(tmp);
00900          } else {
00901             ies->rr_ooo = ntohl(get_unaligned_uint32(data + 2));
00902          }
00903          break;
00904       case IAX_IE_VARIABLE:
00905          ast_copy_string(tmp, (char *)data + 2, len + 1);
00906          tmp2 = strchr(tmp, '=');
00907          if (tmp2)
00908             *tmp2++ = '\0';
00909          else
00910             tmp2 = "";
00911          var = ast_variable_new(tmp, tmp2);
00912          var->next = ies->vars;
00913          ies->vars = var;
00914          break;
00915       default:
00916          snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len);
00917          outputf(tmp);
00918       }
00919       /* Overwrite information element with 0, to null terminate previous portion */
00920       data[0] = 0;
00921       datalen -= (len + 2);
00922       data += (len + 2);
00923    }
00924    /* Null-terminate last field */
00925    *data = '\0';
00926    if (datalen) {
00927       errorf("Invalid information element contents, strange boundary\n");
00928       return -1;
00929    }
00930    return 0;
00931 }

void iax_set_error ( void(*)(const char *data)  output  ) 

void iax_set_output ( void(*)(const char *data)  output  ) 

void iax_showframe ( struct iax_frame f,
struct ast_iax2_full_hdr fhi,
int  rx,
struct sockaddr_in *  sin,
int  datalen 
)

Definition at line 398 of file iax2-parser.c.

References AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_IAX, ast_inet_ntoa(), ast_iax2_full_hdr::csub, ast_iax2_full_hdr::dcallno, dump_ies(), f, IAX_FLAG_FULL, IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iedata, ast_iax2_full_hdr::iseqno, ast_iax2_full_hdr::oseqno, outputf, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::ts, and ast_iax2_full_hdr::type.

Referenced by iax2_send(), raw_hangup(), send_packet(), and socket_process().

00399 {
00400    const char *frames[] = {
00401       "(0?)",
00402       "DTMF_E ",
00403       "VOICE  ",
00404       "VIDEO  ",
00405       "CONTROL",
00406       "NULL   ",
00407       "IAX    ",
00408       "TEXT   ",
00409       "IMAGE  ",
00410       "HTML   ",
00411       "CNG    ",
00412       "MODEM  ",
00413       "DTMF_B ",
00414    };
00415    const char *iaxs[] = {
00416       "(0?)",
00417       "NEW    ",
00418       "PING   ",
00419       "PONG   ",
00420       "ACK    ",
00421       "HANGUP ",
00422       "REJECT ",
00423       "ACCEPT ",
00424       "AUTHREQ",
00425       "AUTHREP",
00426       "INVAL  ",
00427       "LAGRQ  ",
00428       "LAGRP  ",
00429       "REGREQ ",
00430       "REGAUTH",
00431       "REGACK ",
00432       "REGREJ ",
00433       "REGREL ",
00434       "VNAK   ",
00435       "DPREQ  ",
00436       "DPREP  ",
00437       "DIAL   ",
00438       "TXREQ  ",
00439       "TXCNT  ",
00440       "TXACC  ",
00441       "TXREADY",
00442       "TXREL  ",
00443       "TXREJ  ",
00444       "QUELCH ",
00445       "UNQULCH",
00446       "POKE   ",
00447       "PAGE   ",
00448       "MWI    ",
00449       "UNSPRTD",
00450       "TRANSFR",
00451       "PROVISN",
00452       "FWDWNLD",
00453       "FWDATA "
00454    };
00455    const char *cmds[] = {
00456       "(0?)",
00457       "HANGUP ",
00458       "RING   ",
00459       "RINGING",
00460       "ANSWER ",
00461       "BUSY   ",
00462       "TKOFFHK",
00463       "OFFHOOK",
00464       "CONGSTN",
00465       "FLASH  ",
00466       "WINK   ",
00467       "OPTION ",
00468       "RDKEY  ",
00469       "RDUNKEY",
00470       "PROGRES",
00471       "PROCDNG",
00472       "HOLD   ",
00473       "UNHOLD ",
00474       "VIDUPDT", };
00475    struct ast_iax2_full_hdr *fh;
00476    char retries[20];
00477    char class2[20];
00478    char subclass2[20];
00479    const char *class;
00480    const char *subclass;
00481    char *dir;
00482    char tmp[512];
00483 
00484    switch(rx) {
00485    case 0:
00486       dir = "Tx";
00487       break;
00488    case 2:
00489       dir = "TE";
00490       break;
00491    case 3:
00492       dir = "RD";
00493       break;
00494    default:
00495       dir = "Rx";
00496       break;
00497    }
00498    if (f) {
00499       fh = f->data;
00500       snprintf(retries, sizeof(retries), "%03d", f->retries);
00501    } else {
00502       fh = fhi;
00503       if (ntohs(fh->dcallno) & IAX_FLAG_RETRANS)
00504          strcpy(retries, "Yes");
00505       else
00506          strcpy(retries, " No");
00507    }
00508    if (!(ntohs(fh->scallno) & IAX_FLAG_FULL)) {
00509       /* Don't mess with mini-frames */
00510       return;
00511    }
00512    if (fh->type >= (int)sizeof(frames)/(int)sizeof(frames[0])) {
00513       snprintf(class2, sizeof(class2), "(%d?)", fh->type);
00514       class = class2;
00515    } else {
00516       class = frames[(int)fh->type];
00517    }
00518    if (fh->type == AST_FRAME_DTMF_BEGIN || fh->type == AST_FRAME_DTMF_END) {
00519       sprintf(subclass2, "%c", fh->csub);
00520       subclass = subclass2;
00521    } else if (fh->type == AST_FRAME_IAX) {
00522       if (fh->csub >= (int)sizeof(iaxs)/(int)sizeof(iaxs[0])) {
00523          snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub);
00524          subclass = subclass2;
00525       } else {
00526          subclass = iaxs[(int)fh->csub];
00527       }
00528    } else if (fh->type == AST_FRAME_CONTROL) {
00529       if (fh->csub >= (int)sizeof(cmds)/(int)sizeof(cmds[0])) {
00530          snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub);
00531          subclass = subclass2;
00532       } else {
00533          subclass = cmds[(int)fh->csub];
00534       }
00535    } else {
00536       snprintf(subclass2, sizeof(subclass2), "%d", fh->csub);
00537       subclass = subclass2;
00538    }
00539    snprintf(tmp, sizeof(tmp), 
00540        "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s Subclass: %s\n",
00541        dir,
00542        retries, fh->oseqno, fh->iseqno, class, subclass);
00543    outputf(tmp);
00544    snprintf(tmp, sizeof(tmp), 
00545        "   Timestamp: %05lums  SCall: %5.5d  DCall: %5.5d [%s:%d]\n",
00546        (unsigned long)ntohl(fh->ts),
00547        ntohs(fh->scallno) & ~IAX_FLAG_FULL, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS,
00548        ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
00549    outputf(tmp);
00550    if (fh->type == AST_FRAME_IAX)
00551       dump_ies(fh->iedata, datalen);
00552 }


Generated on Mon May 14 04:49:44 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1