Wed Oct 28 11:46:11 2009

Asterisk developer's documentation


iax2-parser.h File Reference

Implementation of the IAX2 protocol. More...

#include "asterisk/linkedlists.h"
#include "asterisk/aes.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)
struct iax_frameiax_frame_new (int direction, int datalen, unsigned int cacheable)
void iax_frame_subclass2str (enum iax_frame_subclass subclass, char *str, size_t len)
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 84 of file iax2-parser.h.

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

#define DIRECTION_OUTGRESS   2

Definition at line 85 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 1134 of file iax2-parser.c.

References ast_atomic_fetchadd_int(), ast_free, AST_LIST_INSERT_HEAD, ast_threadstorage_get(), iax_frame::cacheable, iax_frame::direction, DIRECTION_INGRESS, DIRECTION_OUTGRESS, errorf, frame_cache, FRAME_CACHE_MAX_SIZE, iax_frames::list, and iax_frames::size.

Referenced by iax2_frame_free(), and network_thread().

01135 {
01136 #if !defined(LOW_MEMORY)
01137    struct iax_frames *iax_frames = NULL;
01138 #endif
01139 
01140    /* Note: does not remove from scheduler! */
01141    if (fr->direction == DIRECTION_INGRESS)
01142       ast_atomic_fetchadd_int(&iframes, -1);
01143    else if (fr->direction == DIRECTION_OUTGRESS)
01144       ast_atomic_fetchadd_int(&oframes, -1);
01145    else {
01146       errorf("Attempt to double free frame detected\n");
01147       return;
01148    }
01149    ast_atomic_fetchadd_int(&frames, -1);
01150 
01151 #if !defined(LOW_MEMORY)
01152    if (!fr->cacheable || !(iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
01153       ast_free(fr);
01154       return;
01155    }
01156 
01157    if (iax_frames->size < FRAME_CACHE_MAX_SIZE) {
01158       fr->direction = 0;
01159       AST_LIST_INSERT_HEAD(&iax_frames->list, fr, list);
01160       iax_frames->size++;
01161       return;
01162    }
01163 #endif
01164    ast_free(fr);
01165 }

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

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

References iax_frame::afdatalen, ast_atomic_fetchadd_int(), ast_calloc, ast_calloc_cache, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_threadstorage_get(), iax_frame::cacheable, iax_frame::direction, DIRECTION_INGRESS, frame_cache, iax_frames::list, iax_frame::retrans, and iax_frames::size.

Referenced by iax2_send(), and iaxfrdup2().

01088 {
01089    struct iax_frame *fr = NULL;
01090 
01091 #if !defined(LOW_MEMORY)
01092    struct iax_frames *iax_frames = NULL;
01093 
01094    /* Attempt to get a frame from this thread's cache */
01095    if ((iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
01096       AST_LIST_TRAVERSE_SAFE_BEGIN(&iax_frames->list, fr, list) {
01097          if (fr->afdatalen >= datalen) {
01098             size_t afdatalen = fr->afdatalen;
01099             AST_LIST_REMOVE_CURRENT(list);
01100             iax_frames->size--;
01101             memset(fr, 0, sizeof(*fr));
01102             fr->afdatalen = afdatalen;
01103             break;
01104          }
01105       }
01106       AST_LIST_TRAVERSE_SAFE_END;
01107    }
01108    if (!fr) {
01109       if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen)))
01110          return NULL;
01111       fr->afdatalen = datalen;
01112    }
01113 #else
01114    if (!(fr = ast_calloc(1, sizeof(*fr) + datalen)))
01115       return NULL;
01116    fr->afdatalen = datalen;
01117 #endif
01118 
01119 
01120    fr->direction = direction;
01121    fr->retrans = -1;
01122    fr->cacheable = cacheable;
01123    
01124    if (fr->direction == DIRECTION_INGRESS)
01125       ast_atomic_fetchadd_int(&iframes, 1);
01126    else
01127       ast_atomic_fetchadd_int(&oframes, 1);
01128    
01129    ast_atomic_fetchadd_int(&frames, 1);
01130 
01131    return fr;
01132 }

void iax_frame_subclass2str ( enum iax_frame_subclass  subclass,
char *  str,
size_t  len 
)

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

References ast_copy_string(), IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_CALLTOKEN, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_MWI, IAX_COMMAND_NEW, IAX_COMMAND_PAGE, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_PROVISION, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, and IAX_COMMAND_VNAK.

Referenced by ast_cli_netstats(), handle_cli_iax2_show_channels(), and iax_showframe().

00402 {
00403    const char *cmd = "Unknown";
00404 
00405    /* if an error occurs here during compile, that means a new iax frame subclass
00406     * has been added to the iax_frame_subclass enum.  Add the new subclass to the
00407     * switch case and make sure to update it with a new string representation. */
00408    switch (subclass) {
00409    case IAX_COMMAND_NEW:
00410       cmd = "NEW    ";
00411       break;
00412    case IAX_COMMAND_PING:
00413       cmd = "PING   ";
00414       break;
00415    case IAX_COMMAND_PONG:
00416       cmd = "PONG   ";
00417       break;
00418    case IAX_COMMAND_ACK:
00419       cmd = "ACK    ";
00420       break;
00421    case IAX_COMMAND_HANGUP:
00422       cmd = "HANGUP ";
00423       break;
00424    case IAX_COMMAND_REJECT:
00425       cmd = "REJECT ";
00426       break;
00427    case IAX_COMMAND_ACCEPT:
00428       cmd = "ACCEPT ";
00429       break;
00430    case IAX_COMMAND_AUTHREQ:
00431       cmd = "AUTHREQ";
00432       break;
00433    case IAX_COMMAND_AUTHREP:
00434       cmd = "AUTHREP";
00435       break;
00436    case IAX_COMMAND_INVAL:
00437       cmd = "INVAL  ";
00438       break;
00439    case IAX_COMMAND_LAGRQ:
00440       cmd = "LAGRQ  ";
00441       break;
00442    case IAX_COMMAND_LAGRP:
00443       cmd = "LAGRP  ";
00444       break;
00445    case IAX_COMMAND_REGREQ:
00446       cmd = "REGREQ ";
00447       break;
00448    case IAX_COMMAND_REGAUTH:
00449       cmd = "REGAUTH";
00450       break;
00451    case IAX_COMMAND_REGACK:
00452       cmd = "REGACK ";
00453       break;
00454    case IAX_COMMAND_REGREJ:
00455       cmd = "REGREJ ";
00456       break;
00457    case IAX_COMMAND_REGREL:
00458       cmd = "REGREL ";
00459       break;
00460    case IAX_COMMAND_VNAK:
00461       cmd = "VNAK   ";
00462       break;
00463    case IAX_COMMAND_DPREQ:
00464       cmd = "DPREQ  ";
00465       break;
00466    case IAX_COMMAND_DPREP:
00467       cmd = "DPREP  ";
00468       break;
00469    case IAX_COMMAND_DIAL:
00470       cmd = "DIAL   ";
00471       break;
00472    case IAX_COMMAND_TXREQ:
00473       cmd = "TXREQ  ";
00474       break;
00475    case IAX_COMMAND_TXCNT:
00476       cmd = "TXCNT  ";
00477       break;
00478    case IAX_COMMAND_TXACC:
00479       cmd = "TXACC  ";
00480       break;
00481    case IAX_COMMAND_TXREADY:
00482       cmd = "TXREADY";
00483       break;
00484    case IAX_COMMAND_TXREL:
00485       cmd = "TXREL  ";
00486       break;
00487    case IAX_COMMAND_TXREJ:
00488       cmd = "TXREJ  ";
00489       break;
00490    case IAX_COMMAND_QUELCH:
00491       cmd = "QUELCH ";
00492       break;
00493    case IAX_COMMAND_UNQUELCH:
00494       cmd = "UNQULCH";
00495       break;
00496    case IAX_COMMAND_POKE:
00497       cmd = "POKE   ";
00498       break;
00499    case IAX_COMMAND_PAGE:
00500       cmd = "PAGE   ";
00501       break;
00502    case IAX_COMMAND_MWI:
00503       cmd = "MWI    ";
00504       break;
00505    case IAX_COMMAND_UNSUPPORT:
00506       cmd = "UNSPRTD";
00507       break;
00508    case IAX_COMMAND_TRANSFER:
00509       cmd = "TRANSFR";
00510       break;
00511    case IAX_COMMAND_PROVISION:
00512       cmd = "PROVISN";
00513       break;
00514    case IAX_COMMAND_FWDOWNL:
00515       cmd = "FWDWNLD";
00516       break;
00517    case IAX_COMMAND_FWDATA:
00518       cmd = "FWDATA ";
00519       break;
00520    case IAX_COMMAND_TXMEDIA:
00521       cmd = "TXMEDIA";
00522       break;
00523    case IAX_COMMAND_CALLTOKEN:
00524       cmd = "CTOKEN ";
00525       break;
00526    }
00527    ast_copy_string(str, cmd, len);
00528 }

void iax_frame_wrap ( struct iax_frame fr,
struct ast_frame f 
)

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

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

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

01057 {
01058    fr->af.frametype = f->frametype;
01059    fr->af.subclass = f->subclass;
01060    fr->af.mallocd = 0;           /* Our frame is static relative to the container */
01061    fr->af.datalen = f->datalen;
01062    fr->af.samples = f->samples;
01063    fr->af.offset = AST_FRIENDLY_OFFSET;
01064    fr->af.src = f->src;
01065    fr->af.delivery.tv_sec = 0;
01066    fr->af.delivery.tv_usec = 0;
01067    fr->af.data = fr->afdata;
01068    fr->af.len = f->len;
01069    if (fr->af.datalen) {
01070       size_t copy_len = fr->af.datalen;
01071       if (copy_len > fr->afdatalen) {
01072          ast_log(LOG_ERROR, "Losing frame data because destination buffer size '%d' bytes not big enough for '%d' bytes in the frame\n",
01073             (int) fr->afdatalen, (int) fr->af.datalen);
01074          copy_len = fr->afdatalen;
01075       }
01076 #if __BYTE_ORDER == __LITTLE_ENDIAN
01077       /* We need to byte-swap slinear samples from network byte order */
01078       if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass == AST_FORMAT_SLINEAR)) {
01079          /* 2 bytes / sample for SLINEAR */
01080          ast_swapcopy_samples(fr->af.data, f->data, copy_len / 2);
01081       } else
01082 #endif
01083          memcpy(fr->af.data, f->data, copy_len);
01084    }
01085 }

int iax_get_frames ( void   ) 

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

Referenced by handle_cli_iax2_show_stats().

01180 { return frames; }

int iax_get_iframes ( void   ) 

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

Referenced by handle_cli_iax2_show_stats().

01181 { return iframes; }

int iax_get_oframes ( void   ) 

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

Referenced by handle_cli_iax2_show_stats().

01182 { return oframes; }

const char* iax_ie2str ( int  ie  ) 

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

References ies, and iax2_ie::name.

Referenced by iax_ie_append_raw(), and iax_parse_ies().

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

int iax_ie_append ( struct iax_ie_data ied,
unsigned char  ie 
)

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

References iax_ie_append_raw().

Referenced by iax2_call(), and iax_firmware_append().

00687 {
00688    return iax_ie_append_raw(ied, ie, NULL, 0);
00689 }

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

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

References iax_ie_append_raw().

Referenced by iax2_start_transfer(), and update_registry().

00658 {
00659    return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in));
00660 }

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

Definition at line 681 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().

00682 {
00683    return iax_ie_append_raw(ied, ie, &dat, 1);
00684 }

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

Definition at line 662 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().

00663 {
00664    unsigned int newval;
00665    newval = htonl(value);
00666    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00667 }

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

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

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

Referenced by iax2_call(), 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().

00643 {
00644    char tmp[256];
00645    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00646       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);
00647       errorf(tmp);
00648       return -1;
00649    }
00650    ied->buf[ied->pos++] = ie;
00651    ied->buf[ied->pos++] = datalen;
00652    memcpy(ied->buf + ied->pos, data, datalen);
00653    ied->pos += datalen;
00654    return 0;
00655 }

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

Definition at line 669 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().

00670 {
00671    unsigned short newval;
00672    newval = htons(value);
00673    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00674 }

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 
)

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

References iax_ies::adsicpe, iax_ies::apparent_addr, ast_copy_string(), ast_free, ast_str_create(), ast_str_set(), ast_variable_new(), iax_ies::authmethods, iax_ies::autoanswer, iax_ies::called_context, iax_ies::called_number, iax_ies::calling_ani, iax_ies::calling_name, iax_ies::calling_number, iax_ies::calling_pres, iax_ies::calling_tns, iax_ies::calling_ton, iax_ies::callno, iax_ies::calltoken, iax_ies::calltokendata, iax_ies::capability, iax_ies::cause, iax_ies::causecode, iax_ies::challenge, iax_ies::codec_prefs, iax_ies::datetime, iax_ies::devicetype, iax_ies::dnid, iax_ies::dpstatus, iax_ies::enckey, iax_ies::enckeylen, iax_ies::encmethods, errorf, ast_variable::file, iax_ies::firmwarever, iax_ies::format, iax_ies::fwdata, iax_ies::fwdatalen, iax_ies::fwdesc, 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_CALLTOKEN, 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_OSPTOKEN, 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_MAX_OSPBLOCK_NUM, IAX_RATE_8KHZ, iax_ies::iax_unknown, iax_ies::language, len(), iax_ies::md5_result, iax_ies::msgcount, iax_ies::musiconhold, ast_variable::name, ast_variable::next, iax_ies::ospblocklength, iax_ies::osptokenblock, outputf, iax_ies::password, iax_ies::provver, iax_ies::provverpres, iax_ies::rdnis, iax_ies::refresh, iax_ies::rr_delay, iax_ies::rr_dropped, iax_ies::rr_jitter, iax_ies::rr_loss, iax_ies::rr_ooo, iax_ies::rr_pkts, iax_ies::rsa_result, iax_ies::samprate, iax_ies::serviceident, ast_str::str, str, iax_ies::transferid, iax_ies::username, ast_variable::value, var, iax_ies::vars, and iax_ies::version.

Referenced by socket_process().

00702 {
00703    /* Parse data into information elements */
00704    int len;
00705    int ie;
00706    char tmp[256], *tmp2;
00707    struct ast_variable *var, *var2, *prev;
00708    unsigned int count;
00709    memset(ies, 0, (int)sizeof(struct iax_ies));
00710    ies->msgcount = -1;
00711    ies->firmwarever = -1;
00712    ies->calling_ton = -1;
00713    ies->calling_tns = -1;
00714    ies->calling_pres = -1;
00715    ies->samprate = IAX_RATE_8KHZ;
00716    while(datalen >= 2) {
00717       ie = data[0];
00718       len = data[1];
00719       if (len > datalen - 2) {
00720          errorf("Information element length exceeds message size\n");
00721          return -1;
00722       }
00723       switch(ie) {
00724       case IAX_IE_CALLED_NUMBER:
00725          ies->called_number = (char *)data + 2;
00726          break;
00727       case IAX_IE_CALLING_NUMBER:
00728          ies->calling_number = (char *)data + 2;
00729          break;
00730       case IAX_IE_CALLING_ANI:
00731          ies->calling_ani = (char *)data + 2;
00732          break;
00733       case IAX_IE_CALLING_NAME:
00734          ies->calling_name = (char *)data + 2;
00735          break;
00736       case IAX_IE_CALLED_CONTEXT:
00737          ies->called_context = (char *)data + 2;
00738          break;
00739       case IAX_IE_USERNAME:
00740          ies->username = (char *)data + 2;
00741          break;
00742       case IAX_IE_PASSWORD:
00743          ies->password = (char *)data + 2;
00744          break;
00745       case IAX_IE_CODEC_PREFS:
00746          ies->codec_prefs = (char *)data + 2;
00747          break;
00748       case IAX_IE_CAPABILITY:
00749          if (len != (int)sizeof(unsigned int)) {
00750             snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00751             errorf(tmp);
00752          } else
00753             ies->capability = ntohl(get_unaligned_uint32(data + 2));
00754          break;
00755       case IAX_IE_FORMAT:
00756          if (len != (int)sizeof(unsigned int)) {
00757             snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00758             errorf(tmp);
00759          } else
00760             ies->format = ntohl(get_unaligned_uint32(data + 2));
00761          break;
00762       case IAX_IE_LANGUAGE:
00763          ies->language = (char *)data + 2;
00764          break;
00765       case IAX_IE_VERSION:
00766          if (len != (int)sizeof(unsigned short)) {
00767             snprintf(tmp, (int)sizeof(tmp),  "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00768             errorf(tmp);
00769          } else
00770             ies->version = ntohs(get_unaligned_uint16(data + 2));
00771          break;
00772       case IAX_IE_ADSICPE:
00773          if (len != (int)sizeof(unsigned short)) {
00774             snprintf(tmp, (int)sizeof(tmp), "Expecting adsicpe to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00775             errorf(tmp);
00776          } else
00777             ies->adsicpe = ntohs(get_unaligned_uint16(data + 2));
00778          break;
00779       case IAX_IE_SAMPLINGRATE:
00780          if (len != (int)sizeof(unsigned short)) {
00781             snprintf(tmp, (int)sizeof(tmp), "Expecting samplingrate to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00782             errorf(tmp);
00783          } else
00784             ies->samprate = ntohs(get_unaligned_uint16(data + 2));
00785          break;
00786       case IAX_IE_DNID:
00787          ies->dnid = (char *)data + 2;
00788          break;
00789       case IAX_IE_RDNIS:
00790          ies->rdnis = (char *)data + 2;
00791          break;
00792       case IAX_IE_AUTHMETHODS:
00793          if (len != (int)sizeof(unsigned short))  {
00794             snprintf(tmp, (int)sizeof(tmp), "Expecting authmethods to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00795             errorf(tmp);
00796          } else
00797             ies->authmethods = ntohs(get_unaligned_uint16(data + 2));
00798          break;
00799       case IAX_IE_ENCRYPTION:
00800          if (len != (int)sizeof(unsigned short))  {
00801             snprintf(tmp, (int)sizeof(tmp), "Expecting encryption to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00802             errorf(tmp);
00803          } else
00804             ies->encmethods = ntohs(get_unaligned_uint16(data + 2));
00805          break;
00806       case IAX_IE_CHALLENGE:
00807          ies->challenge = (char *)data + 2;
00808          break;
00809       case IAX_IE_MD5_RESULT:
00810          ies->md5_result = (char *)data + 2;
00811          break;
00812       case IAX_IE_RSA_RESULT:
00813          ies->rsa_result = (char *)data + 2;
00814          break;
00815       case IAX_IE_APPARENT_ADDR:
00816          ies->apparent_addr = ((struct sockaddr_in *)(data + 2));
00817          break;
00818       case IAX_IE_REFRESH:
00819          if (len != (int)sizeof(unsigned short)) {
00820             snprintf(tmp, (int)sizeof(tmp),  "Expecting refresh to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00821             errorf(tmp);
00822          } else
00823             ies->refresh = ntohs(get_unaligned_uint16(data + 2));
00824          break;
00825       case IAX_IE_DPSTATUS:
00826          if (len != (int)sizeof(unsigned short)) {
00827             snprintf(tmp, (int)sizeof(tmp),  "Expecting dpstatus to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00828             errorf(tmp);
00829          } else
00830             ies->dpstatus = ntohs(get_unaligned_uint16(data + 2));
00831          break;
00832       case IAX_IE_CALLNO:
00833          if (len != (int)sizeof(unsigned short)) {
00834             snprintf(tmp, (int)sizeof(tmp),  "Expecting callno to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00835             errorf(tmp);
00836          } else
00837             ies->callno = ntohs(get_unaligned_uint16(data + 2));
00838          break;
00839       case IAX_IE_CAUSE:
00840          ies->cause = (char *)data + 2;
00841          break;
00842       case IAX_IE_CAUSECODE:
00843          if (len != 1) {
00844             snprintf(tmp, (int)sizeof(tmp), "Expecting causecode to be single byte but was %d\n", len);
00845             errorf(tmp);
00846          } else {
00847             ies->causecode = data[2];
00848          }
00849          break;
00850       case IAX_IE_IAX_UNKNOWN:
00851          if (len == 1)
00852             ies->iax_unknown = data[2];
00853          else {
00854             snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len);
00855             errorf(tmp);
00856          }
00857          break;
00858       case IAX_IE_MSGCOUNT:
00859          if (len != (int)sizeof(unsigned short)) {
00860             snprintf(tmp, (int)sizeof(tmp), "Expecting msgcount to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00861             errorf(tmp);
00862          } else
00863             ies->msgcount = ntohs(get_unaligned_uint16(data + 2));   
00864          break;
00865       case IAX_IE_AUTOANSWER:
00866          ies->autoanswer = 1;
00867          break;
00868       case IAX_IE_MUSICONHOLD:
00869          ies->musiconhold = 1;
00870          break;
00871       case IAX_IE_TRANSFERID:
00872          if (len != (int)sizeof(unsigned int)) {
00873             snprintf(tmp, (int)sizeof(tmp), "Expecting transferid to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00874             errorf(tmp);
00875          } else
00876             ies->transferid = ntohl(get_unaligned_uint32(data + 2));
00877          break;
00878       case IAX_IE_DATETIME:
00879          if (len != (int)sizeof(unsigned int)) {
00880             snprintf(tmp, (int)sizeof(tmp), "Expecting date/time to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00881             errorf(tmp);
00882          } else
00883             ies->datetime = ntohl(get_unaligned_uint32(data + 2));
00884          break;
00885       case IAX_IE_FIRMWAREVER:
00886          if (len != (int)sizeof(unsigned short)) {
00887             snprintf(tmp, (int)sizeof(tmp), "Expecting firmwarever to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00888             errorf(tmp);
00889          } else
00890             ies->firmwarever = ntohs(get_unaligned_uint16(data + 2));   
00891          break;
00892       case IAX_IE_DEVICETYPE:
00893          ies->devicetype = (char *)data + 2;
00894          break;
00895       case IAX_IE_SERVICEIDENT:
00896          ies->serviceident = (char *)data + 2;
00897          break;
00898       case IAX_IE_FWBLOCKDESC:
00899          if (len != (int)sizeof(unsigned int)) {
00900             snprintf(tmp, (int)sizeof(tmp), "Expected block desc to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00901             errorf(tmp);
00902          } else
00903             ies->fwdesc = ntohl(get_unaligned_uint32(data + 2));
00904          break;
00905       case IAX_IE_FWBLOCKDATA:
00906          ies->fwdata = data + 2;
00907          ies->fwdatalen = len;
00908          break;
00909       case IAX_IE_ENCKEY:
00910          ies->enckey = data + 2;
00911          ies->enckeylen = len;
00912          break;
00913       case IAX_IE_PROVVER:
00914          if (len != (int)sizeof(unsigned int)) {
00915             snprintf(tmp, (int)sizeof(tmp), "Expected provisioning version to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00916             errorf(tmp);
00917          } else {
00918             ies->provverpres = 1;
00919             ies->provver = ntohl(get_unaligned_uint32(data + 2));
00920          }
00921          break;
00922       case IAX_IE_CALLINGPRES:
00923          if (len == 1)
00924             ies->calling_pres = data[2];
00925          else {
00926             snprintf(tmp, (int)sizeof(tmp), "Expected single byte callingpres, but was %d long\n", len);
00927             errorf(tmp);
00928          }
00929          break;
00930       case IAX_IE_CALLINGTON:
00931          if (len == 1)
00932             ies->calling_ton = data[2];
00933          else {
00934             snprintf(tmp, (int)sizeof(tmp), "Expected single byte callington, but was %d long\n", len);
00935             errorf(tmp);
00936          }
00937          break;
00938       case IAX_IE_CALLINGTNS:
00939          if (len != (int)sizeof(unsigned short)) {
00940             snprintf(tmp, (int)sizeof(tmp), "Expecting callingtns to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00941             errorf(tmp);
00942          } else
00943             ies->calling_tns = ntohs(get_unaligned_uint16(data + 2));   
00944          break;
00945                case IAX_IE_RR_JITTER:
00946                        if (len != (int)sizeof(unsigned int)) {
00947                                snprintf(tmp, (int)sizeof(tmp), "Expected jitter rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00948                                errorf(tmp);
00949                        } else {
00950                                ies->rr_jitter = ntohl(get_unaligned_uint32(data + 2));
00951                        }
00952                        break;
00953                case IAX_IE_RR_LOSS:
00954                        if (len != (int)sizeof(unsigned int)) {
00955                                snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00956                                errorf(tmp);
00957                        } else {
00958                                ies->rr_loss = ntohl(get_unaligned_uint32(data + 2));
00959                        }
00960                        break;
00961                case IAX_IE_RR_PKTS:
00962                        if (len != (int)sizeof(unsigned int)) {
00963                                snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00964                                errorf(tmp);
00965                        } else {
00966                                ies->rr_pkts = ntohl(get_unaligned_uint32(data + 2));
00967                        }
00968                        break;
00969                case IAX_IE_RR_DELAY:
00970                        if (len != (int)sizeof(unsigned short)) {
00971                                snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00972                         errorf(tmp);
00973                        } else {
00974                                ies->rr_delay = ntohs(get_unaligned_uint16(data + 2));
00975                        }
00976                        break;
00977       case IAX_IE_RR_DROPPED:
00978          if (len != (int)sizeof(unsigned int)) {
00979             snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00980             errorf(tmp);
00981          } else {
00982             ies->rr_dropped = ntohl(get_unaligned_uint32(data + 2));
00983          }
00984          break;
00985       case IAX_IE_RR_OOO:
00986          if (len != (int)sizeof(unsigned int)) {
00987             snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00988             errorf(tmp);
00989          } else {
00990             ies->rr_ooo = ntohl(get_unaligned_uint32(data + 2));
00991          }
00992          break;
00993       case IAX_IE_VARIABLE:
00994          ast_copy_string(tmp, (char *)data + 2, len + 1);
00995          tmp2 = strchr(tmp, '=');
00996          if (tmp2)
00997             *tmp2++ = '\0';
00998          else
00999             tmp2 = "";
01000          {
01001             struct ast_str *str = ast_str_create(16);
01002             /* Existing variable or new variable? */
01003             for (var2 = ies->vars, prev = NULL; var2; prev = var2, var2 = var2->next) {
01004                if (strcmp(tmp, var2->name) == 0) {
01005                   ast_str_set(&str, 0, "%s%s", var2->value, tmp2);
01006                   var = ast_variable_new(tmp, str->str, var2->file);
01007                   var->next = var2->next;
01008                   if (prev)
01009                      prev->next = var;
01010                   else
01011                      ies->vars = var;
01012                   ast_free(var2);
01013                   break;
01014                }
01015             }
01016          }
01017          if (!var2) {
01018             var = ast_variable_new(tmp, tmp2, "");
01019             var->next = ies->vars;
01020             ies->vars = var;
01021          }
01022          break;
01023       case IAX_IE_OSPTOKEN:
01024          if ((count = data[2]) < IAX_MAX_OSPBLOCK_NUM) {
01025             ies->osptokenblock[count] = (char *)data + 2 + 1;
01026             ies->ospblocklength[count] = len - 1;
01027          } else {
01028             snprintf(tmp, (int)sizeof(tmp), "Expected OSP token block index to be 0~%d but was %d\n", IAX_MAX_OSPBLOCK_NUM - 1, count);
01029             errorf(tmp);
01030          }
01031          break;
01032       case IAX_IE_CALLTOKEN:
01033          if (len) {
01034             ies->calltokendata = (unsigned char *) data + 2;
01035          }
01036          ies->calltoken = 1;
01037          break;
01038       default:
01039          snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len);
01040          outputf(tmp);
01041       }
01042       /* Overwrite information element with 0, to null terminate previous portion */
01043       data[0] = 0;
01044       datalen -= (len + 2);
01045       data += (len + 2);
01046    }
01047    /* Null-terminate last field */
01048    *data = '\0';
01049    if (datalen) {
01050       errorf("Invalid information element contents, strange boundary\n");
01051       return -1;
01052    }
01053    return 0;
01054 }

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 530 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, iax_frame::data, ast_iax2_full_hdr::dcallno, dir, dump_ies(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, iax_frame_subclass2str(), ast_iax2_full_hdr::iedata, ast_iax2_full_hdr::iseqno, ast_iax2_full_hdr::oseqno, outputf, iax_frame::retries, 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().

00531 {
00532    const char *frames[] = {
00533       "(0?)",
00534       "DTMF_E ",
00535       "VOICE  ",
00536       "VIDEO  ",
00537       "CONTROL",
00538       "NULL   ",
00539       "IAX    ",
00540       "TEXT   ",
00541       "IMAGE  ",
00542       "HTML   ",
00543       "CNG    ",
00544       "MODEM  ",
00545       "DTMF_B ",
00546    };
00547    const char *cmds[] = {
00548       "(0?)",
00549       "HANGUP ",
00550       "RING   ",
00551       "RINGING",
00552       "ANSWER ",
00553       "BUSY   ",
00554       "TKOFFHK",
00555       "OFFHOOK",
00556       "CONGSTN",
00557       "FLASH  ",
00558       "WINK   ",
00559       "OPTION ",
00560       "RDKEY  ",
00561       "RDUNKEY",
00562       "PROGRES",
00563       "PROCDNG",
00564       "HOLD   ",
00565       "UNHOLD ",
00566       "VIDUPDT", };
00567    struct ast_iax2_full_hdr *fh;
00568    char retries[20];
00569    char class2[20];
00570    char subclass2[20];
00571    const char *class;
00572    const char *subclass;
00573    char *dir;
00574    char tmp[512];
00575 
00576    switch(rx) {
00577    case 0:
00578       dir = "Tx";
00579       break;
00580    case 2:
00581       dir = "TE";
00582       break;
00583    case 3:
00584       dir = "RD";
00585       break;
00586    default:
00587       dir = "Rx";
00588       break;
00589    }
00590    if (f) {
00591       fh = f->data;
00592       snprintf(retries, sizeof(retries), "%03d", f->retries);
00593    } else {
00594       fh = fhi;
00595       if (ntohs(fh->dcallno) & IAX_FLAG_RETRANS)
00596          strcpy(retries, "Yes");
00597       else
00598          strcpy(retries, " No");
00599    }
00600    if (!(ntohs(fh->scallno) & IAX_FLAG_FULL)) {
00601       /* Don't mess with mini-frames */
00602       return;
00603    }
00604    if (fh->type >= (int)sizeof(frames)/(int)sizeof(frames[0])) {
00605       snprintf(class2, sizeof(class2), "(%d?)", fh->type);
00606       class = class2;
00607    } else {
00608       class = frames[(int)fh->type];
00609    }
00610    if (fh->type == AST_FRAME_DTMF_BEGIN || fh->type == AST_FRAME_DTMF_END) {
00611       sprintf(subclass2, "%c", fh->csub);
00612       subclass = subclass2;
00613    } else if (fh->type == AST_FRAME_IAX) {
00614          iax_frame_subclass2str((int)fh->csub, subclass2, sizeof(subclass2));
00615          subclass = subclass2;
00616    } else if (fh->type == AST_FRAME_CONTROL) {
00617       if (fh->csub >= (int)sizeof(cmds)/(int)sizeof(cmds[0])) {
00618          snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub);
00619          subclass = subclass2;
00620       } else {
00621          subclass = cmds[(int)fh->csub];
00622       }
00623    } else {
00624       snprintf(subclass2, sizeof(subclass2), "%d", fh->csub);
00625       subclass = subclass2;
00626    }
00627    snprintf(tmp, sizeof(tmp), 
00628        "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s Subclass: %s\n",
00629        dir,
00630        retries, fh->oseqno, fh->iseqno, class, subclass);
00631    outputf(tmp);
00632    snprintf(tmp, sizeof(tmp), 
00633        "   Timestamp: %05lums  SCall: %5.5d  DCall: %5.5d [%s:%d]\n",
00634        (unsigned long)ntohl(fh->ts),
00635        ntohs(fh->scallno) & ~IAX_FLAG_FULL, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS,
00636        ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
00637    outputf(tmp);
00638    if (fh->type == AST_FRAME_IAX)
00639       dump_ies(fh->iedata, datalen);
00640 }


Generated on Wed Oct 28 11:46:11 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6