Fri Nov 12 12:04:13 2010

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 1168 of file iax2-parser.c.

References iax_frame::afdatalen, ast_atomic_fetchadd_int(), ast_free, AST_LIST_FIRST, AST_LIST_INSERT_HEAD, AST_LIST_INSERT_TAIL, 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().

01169 {
01170 #if !defined(LOW_MEMORY)
01171    struct iax_frames *iax_frames = NULL;
01172 #endif
01173 
01174    /* Note: does not remove from scheduler! */
01175    if (fr->direction == DIRECTION_INGRESS)
01176       ast_atomic_fetchadd_int(&iframes, -1);
01177    else if (fr->direction == DIRECTION_OUTGRESS)
01178       ast_atomic_fetchadd_int(&oframes, -1);
01179    else {
01180       errorf("Attempt to double free frame detected\n");
01181       return;
01182    }
01183    ast_atomic_fetchadd_int(&frames, -1);
01184 
01185 #if !defined(LOW_MEMORY)
01186    if (!fr->cacheable || !(iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
01187       ast_free(fr);
01188       return;
01189    }
01190 
01191    if (iax_frames->size < FRAME_CACHE_MAX_SIZE) {
01192       fr->direction = 0;
01193       /* Pseudo-sort: keep smaller frames at the top of the list. This should
01194        * increase the chance that we pick the smallest applicable frame for use. */
01195       if (AST_LIST_FIRST(&iax_frames->list) && AST_LIST_FIRST(&iax_frames->list)->afdatalen < fr->afdatalen) {
01196          AST_LIST_INSERT_TAIL(&iax_frames->list, fr, list);
01197       } else {
01198          AST_LIST_INSERT_HEAD(&iax_frames->list, fr, list);
01199       }
01200       iax_frames->size++;
01201       return;
01202    }
01203 #endif
01204    ast_free(fr);
01205 }

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

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

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

Referenced by iax2_send(), and iaxfrdup2().

01111 {
01112    struct iax_frame *fr = NULL;
01113 
01114 #if !defined(LOW_MEMORY)
01115    struct iax_frames *iax_frames = NULL;
01116    struct iax_frame *smallest = NULL;
01117 
01118    /* Attempt to get a frame from this thread's cache */
01119    if ((iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
01120       smallest = AST_LIST_FIRST(&iax_frames->list);
01121       AST_LIST_TRAVERSE_SAFE_BEGIN(&iax_frames->list, fr, list) {
01122          if (fr->afdatalen >= datalen) {
01123             size_t afdatalen = fr->afdatalen;
01124             AST_LIST_REMOVE_CURRENT(list);
01125             iax_frames->size--;
01126             memset(fr, 0, sizeof(*fr));
01127             fr->afdatalen = afdatalen;
01128             break;
01129          } else if (smallest->afdatalen > fr->afdatalen) {
01130             smallest = fr;
01131          }
01132       }
01133       AST_LIST_TRAVERSE_SAFE_END;
01134    }
01135    if (!fr) {
01136       if (iax_frames->size >= FRAME_CACHE_MAX_SIZE && smallest) {
01137          /* Make useless cache into something more useful */
01138          AST_LIST_REMOVE(&iax_frames->list, smallest, list);
01139          if (!(fr = ast_realloc(smallest, sizeof(*fr) + datalen))) {
01140             AST_LIST_INSERT_TAIL(&iax_frames->list, smallest, list);
01141             return NULL;
01142          }
01143       } else if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen)))
01144          return NULL;
01145       fr->afdatalen = datalen;
01146    }
01147 #else
01148    if (!(fr = ast_calloc(1, sizeof(*fr) + datalen)))
01149       return NULL;
01150    fr->afdatalen = datalen;
01151 #endif
01152 
01153 
01154    fr->direction = direction;
01155    fr->retrans = -1;
01156    fr->cacheable = cacheable;
01157    
01158    if (fr->direction == DIRECTION_INGRESS)
01159       ast_atomic_fetchadd_int(&iframes, 1);
01160    else
01161       ast_atomic_fetchadd_int(&oframes, 1);
01162    
01163    ast_atomic_fetchadd_int(&frames, 1);
01164 
01165    return fr;
01166 }

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

Definition at line 411 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_RTKEY, 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().

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

void iax_frame_wrap ( struct iax_frame fr,
struct ast_frame f 
)

Definition at line 1079 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::ptr, ast_frame::samples, ast_frame::src, and ast_frame::subclass.

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

01080 {
01081    fr->af.frametype = f->frametype;
01082    fr->af.subclass = f->subclass;
01083    fr->af.mallocd = 0;           /* Our frame is static relative to the container */
01084    fr->af.datalen = f->datalen;
01085    fr->af.samples = f->samples;
01086    fr->af.offset = AST_FRIENDLY_OFFSET;
01087    fr->af.src = f->src;
01088    fr->af.delivery.tv_sec = 0;
01089    fr->af.delivery.tv_usec = 0;
01090    fr->af.data.ptr = fr->afdata;
01091    fr->af.len = f->len;
01092    if (fr->af.datalen) {
01093       size_t copy_len = fr->af.datalen;
01094       if (copy_len > fr->afdatalen) {
01095          ast_log(LOG_ERROR, "Losing frame data because destination buffer size '%d' bytes not big enough for '%d' bytes in the frame\n",
01096             (int) fr->afdatalen, (int) fr->af.datalen);
01097          copy_len = fr->afdatalen;
01098       }
01099 #if __BYTE_ORDER == __LITTLE_ENDIAN
01100       /* We need to byte-swap slinear samples from network byte order */
01101       if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass == AST_FORMAT_SLINEAR)) {
01102          /* 2 bytes / sample for SLINEAR */
01103          ast_swapcopy_samples(fr->af.data.ptr, f->data.ptr, copy_len / 2);
01104       } else
01105 #endif
01106          memcpy(fr->af.data.ptr, f->data.ptr, copy_len);
01107    }
01108 }

int iax_get_frames ( void   ) 

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

Referenced by handle_cli_iax2_show_stats().

01220 { return frames; }

int iax_get_iframes ( void   ) 

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

Referenced by handle_cli_iax2_show_stats().

01221 { return iframes; }

int iax_get_oframes ( void   ) 

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

Referenced by handle_cli_iax2_show_stats().

01222 { return oframes; }

const char* iax_ie2str ( int  ie  ) 

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

References ARRAY_LEN, infoelts, and iax2_ie::name.

Referenced by iax_ie_append_raw(), and iax_parse_ies().

00303 {
00304    int x;
00305    for (x = 0; x < ARRAY_LEN(infoelts); x++) {
00306       if (infoelts[x].ie == ie)
00307          return infoelts[x].name;
00308    }
00309    return "Unknown IE";
00310 }

int iax_ie_append ( struct iax_ie_data ied,
unsigned char  ie 
)

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

References iax_ie_append_raw().

Referenced by iax2_call(), and iax_firmware_append().

00703 {
00704    return iax_ie_append_raw(ied, ie, NULL, 0);
00705 }

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

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

References iax_ie_append_raw().

Referenced by iax2_start_transfer(), and update_registry().

00674 {
00675    return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in));
00676 }

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

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

00698 {
00699    return iax_ie_append_raw(ied, ie, &dat, 1);
00700 }

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

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

00679 {
00680    unsigned int newval;
00681    newval = htonl(value);
00682    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00683 }

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

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

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

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

00659 {
00660    char tmp[256];
00661    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00662       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);
00663       errorf(tmp);
00664       return -1;
00665    }
00666    ied->buf[ied->pos++] = ie;
00667    ied->buf[ied->pos++] = datalen;
00668    memcpy(ied->buf + ied->pos, data, datalen);
00669    ied->pos += datalen;
00670    return 0;
00671 }

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

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

00686 {
00687    unsigned short newval;
00688    newval = htons(value);
00689    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00690 }

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 717 of file iax2-parser.c.

References iax_ies::adsicpe, iax_ies::apparent_addr, ast_copy_string(), ast_free, ast_str_buffer(), 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, str, iax_ies::transferid, iax_ies::username, ast_variable::value, var, iax_ies::vars, and iax_ies::version.

Referenced by socket_process().

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

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 543 of file iax2-parser.c.

References ARRAY_LEN, 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 iax_outputframe(), and send_packet().

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


Generated by  doxygen 1.6.2