Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:59 2009

## Asterisk developer's documentation

# iax2-parser.h File Reference

Implementation of the IAX2 protocol. More...

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_frame * | iax_frame_new (int direction, int datalen)
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, 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, 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, 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 78 of file iax2-parser.h.

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

#define DIRECTION_OUTGRESS 2

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

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

Referenced by iax2_frame_free(), and network_thread().

    00951 {
    00952    /* Note: does not remove from scheduler! */
    00953    if (fr->direction == DIRECTION_INGRESS)
    00954       iframes--;
    00955    else if (fr->direction == DIRECTION_OUTGRESS)
    00956       oframes--;
    00957    else {
    00958       errorf("Attempt to double free frame detected\n");
    00959       return;
    00960    }
    00961    fr->direction = 0;
    00962    free(fr);
    00963    frames--;
    00964 }

struct iax_frame* iax_frame_new | ( | int | direction,
|  | int | datalen |
| ) |  |  | `[read]`

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

References iax_frame::afdatalen, iax_frame::direction, DIRECTION_INGRESS, malloc, and iax_frame::retrans.

Referenced by iax2_send(), and iaxfrdup2().

    00934 {
    00935    struct iax_frame *fr;
    00936    fr = malloc((int)sizeof(struct iax_frame) + datalen);
    00937    if (fr) {
    00938       fr->afdatalen = datalen;
    00939       fr->direction = direction;
    00940       fr->retrans = -1;
    00941       frames++;
    00942       if (fr->direction == DIRECTION_INGRESS)
    00943          iframes++;
    00944       else
    00945          oframes++;
    00946    }
    00947    return fr;
    00948 }

void iax_frame_wrap | ( | struct iax_frame * | fr,
|  | struct ast_frame * | f |
| ) |  |  |

Definition at line 903 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, LOG_ERROR, ast_frame::mallocd, ast_frame::offset, ast_frame::samples, ast_frame::src, and ast_frame::subclass.

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

    00904 {
    00905    fr->af.frametype = f->frametype;
    00906    fr->af.subclass = f->subclass;
    00907    fr->af.mallocd = 0;           /* Our frame is static relative to the container */
    00908    fr->af.datalen = f->datalen;
    00909    fr->af.samples = f->samples;
    00910    fr->af.offset = AST_FRIENDLY_OFFSET;
    00911    fr->af.src = f->src;
    00912    fr->af.delivery.tv_sec = 0;
    00913    fr->af.delivery.tv_usec = 0;
    00914    fr->af.data = fr->afdata;
    00915    if (fr->af.datalen) {
    00916       size_t copy_len = fr->af.datalen;
    00917       if (copy_len > fr->afdatalen) {
    00918          ast_log(LOG_ERROR, "Losing frame data because destination buffer size '%d' bytes not big enough for '%d' bytes in the frame\n",
    00919             (int) fr->afdatalen, (int) fr->af.datalen);
    00920          copy_len = fr->afdatalen;
    00921       }
    00922 #if __BYTE_ORDER == __LITTLE_ENDIAN
    00923       /* We need to byte-swap slinear samples from network byte order */
    00924       if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass == AST_FORMAT_SLINEAR)) {
    00925          /* 2 bytes / sample for SLINEAR */
    00926          ast_swapcopy_samples(fr->af.data, f->data, copy_len / 2);
    00927       } else
    00928 #endif
    00929          memcpy(fr->af.data, f->data, copy_len);
    00930    }
    00931 }

int iax_get_frames | ( | void |  | ) |

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

Referenced by iax2_show_stats().

    00966 { return frames; }

int iax_get_iframes | ( | void |  | ) |

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

Referenced by iax2_show_stats().

    00967 { return iframes; }

int iax_get_oframes | ( | void |  | ) |

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

Referenced by iax2_show_stats().

    00968 { return oframes; }

const char* iax_ie2str | ( | int | ie | ) |

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

References ies, and iax2_ie::name.

Referenced by iax_ie_append_raw(), and iax_parse_ies().

    00276 {
    00277    int x;
    00278    for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
    00279       if (ies[x].ie == ie)
    00280          return ies[x].name;
    00281    }
    00282    return "Unknown IE";
    00283 }

int iax_ie_append | ( | struct iax_ie_data * | ied,
|  | unsigned char | ie |
| ) |  |  |

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

References iax_ie_append_raw().

Referenced by iax2_call(), and iax_firmware_append().

    00575 {
    00576    return iax_ie_append_raw(ied, ie, NULL, 0);
    00577 }

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

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

References iax_ie_append_raw().

Referenced by iax2_start_transfer(), and update_registry().

    00546 {
    00547    return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in));
    00548 }

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

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

References iax_ie_append_raw().

Referenced by auth_reject(), authenticate_request(), auto_hangup(), iax2_call(), iax2_hangup(), iax_provision_build(), and socket_read().

    00570 {
    00571    return iax_ie_append_raw(ied, ie, &dat, 1);
    00572 }

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

Definition at line 550 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_read(), try_transfer(), and update_registry().

    00551 {
    00552    unsigned int newval;
    00553    newval = htonl(value);
    00554    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
    00555 }

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

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

    00531 {
    00532    char tmp[256];
    00533    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
    00534       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);
    00535       errorf(tmp);
    00536       return -1;
    00537    }
    00538    ied->buf[ied->pos++] = ie;
    00539    ied->buf[ied->pos++] = datalen;
    00540    memcpy(ied->buf + ied->pos, data, datalen);
    00541    ied->pos += datalen;
    00542    return 0;
    00543 }

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

Definition at line 557 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_read(), and update_registry().

    00558 {
    00559    unsigned short newval;
    00560    newval = htons(value);
    00561    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
    00562 }

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

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

References iax_ie_append_raw().

Referenced by auth_reject(), authenticate(), authenticate_request(), auto_hangup(), cache_get_callno_locked(), dp_lookup(), handle_call_token(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_transfer(), iax_provision_build(), registry_authrequest(), registry_rerequest(), resend_with_token(), socket_read(), and update_registry().

    00565 {
    00566    return iax_ie_append_raw(ied, ie, str, strlen(str));
    00567 }

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

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

References iax_ies::adsicpe, iax_ies::apparent_addr, 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, 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_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_VERSION, IAX_RATE_8KHZ, iax_ies::iax_unknown, iax_ies::language, iax_ies::md5_result, iax_ies::msgcount, iax_ies::musiconhold, 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, iax_ies::transferid, iax_ies::username, and iax_ies::version.

Referenced by socket_read().

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

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

References AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_IAX, ast_inet_ntoa(), ast_iax2_full_hdr::csub, iax_frame::data, ast_iax2_full_hdr::dcallno, dump_ies(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, iaxs, 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_read().

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