int decode_lcs_client_identity(LcsClientIdentity *lcsclientidentity, uint8_t iei, uint8_t *buffer, uint32_t len)
{
  int decoded = 0;
  uint8_t ielen = 0;
  int decode_result;

  if (iei > 0) {
    CHECK_IEI_DECODER(iei, *buffer);
    decoded++;
  }

  ielen = *(buffer + decoded);
  decoded++;
  CHECK_LENGTH_DECODER(len - decoded, ielen);

  if ((decode_result = decode_octet_string(&lcsclientidentity->lcsclientidentityvalue, ielen, buffer + decoded, len - decoded)) < 0)
    return decode_result;
  else
    decoded += decode_result;

#if defined (NAS_DEBUG)
  dump_lcs_client_identity_xml(lcsclientidentity, iei);
#endif
  return decoded;
}
int
decode_authentication_parameter_autn (
  AuthenticationParameterAutn * authenticationparameterautn,
  uint8_t iei,
  uint8_t * buffer,
  uint32_t len)
{
  int                                     decoded = 0;
  uint8_t                                 ielen = 0;
  int                                     decode_result;

  if (iei > 0) {
    CHECK_IEI_DECODER (iei, *buffer);
    decoded++;
  }

  ielen = *(buffer + decoded);
  decoded++;
  CHECK_LENGTH_DECODER (len - decoded, ielen);

  if ((decode_result = decode_octet_string (&authenticationparameterautn->autn, ielen, buffer + decoded, len - decoded)) < 0)
    return decode_result;
  else
    decoded += decode_result;

#if NAS_DEBUG
  dump_authentication_parameter_autn_xml (authenticationparameterautn, iei);
#endif
  return decoded;
}
int
decode_daylight_saving_time (
  DaylightSavingTime * daylightsavingtime,
  uint8_t iei,
  uint8_t * buffer,
  uint32_t len)
{
  int                                     decoded = 0;
  uint8_t                                 ielen = 0;

  if (iei > 0) {
    CHECK_IEI_DECODER (iei, *buffer);
    decoded++;
  }

  ielen = *(buffer + decoded);
  decoded++;
  CHECK_LENGTH_DECODER (len - decoded, ielen);
  *daylightsavingtime = *buffer & 0x3;
  decoded++;
#if NAS_DEBUG
  dump_daylight_saving_time_xml (daylightsavingtime, iei);
#endif
  return decoded;
}
int
decode_voice_domain_preference_and_ue_usage_setting (
  VoiceDomainPreferenceAndUeUsageSetting * voicedomainpreferenceandueusagesetting,
  uint8_t iei,
  uint8_t * buffer,
  uint32_t len)
{
  int                                     decoded = 0;
  uint8_t                                 ielen = 0;

  if (iei > 0) {
    CHECK_IEI_DECODER (iei, *buffer);
    decoded++;
  }

  memset (voicedomainpreferenceandueusagesetting, 0, sizeof (VoiceDomainPreferenceAndUeUsageSetting));
  ielen = *(buffer + decoded);
  decoded++;
  CHECK_LENGTH_DECODER (len - decoded, ielen);
  voicedomainpreferenceandueusagesetting->ue_usage_setting = (*(buffer + decoded) >> 2) & 0x1;
  voicedomainpreferenceandueusagesetting->voice_domain_for_eutran = *(buffer + decoded) & 0x3;
  decoded++;
#if NAS_DEBUG
  dump_voice_domain_preference_and_ue_usage_setting_xml (voicedomainpreferenceandueusagesetting, iei);
#endif
  return decoded;
}
int decode_tracking_area_identity_list(TrackingAreaIdentityList *trackingareaidentitylist, uint8_t iei, uint8_t *buffer, uint32_t len)
{
  int decoded = 0;
  uint8_t ielen = 0;

  if (iei > 0) {
    CHECK_IEI_DECODER(iei, *buffer);
    decoded++;
  }

  ielen = *(buffer + decoded);
  decoded++;
  CHECK_LENGTH_DECODER(len - decoded, ielen);
  trackingareaidentitylist->typeoflist = (*(buffer + decoded) >> 5) & 0x3;
  trackingareaidentitylist->numberofelements = *(buffer + decoded) & 0x1f;
  decoded++;
  trackingareaidentitylist->mccdigit2 = (*(buffer + decoded) >> 4) & 0xf;
  trackingareaidentitylist->mccdigit1 = *(buffer + decoded) & 0xf;
  decoded++;
  trackingareaidentitylist->mncdigit3 = (*(buffer + decoded) >> 4) & 0xf;
  trackingareaidentitylist->mccdigit3 = *(buffer + decoded) & 0xf;
  decoded++;
  trackingareaidentitylist->mncdigit2 = (*(buffer + decoded) >> 4) & 0xf;
  trackingareaidentitylist->mncdigit1 = *(buffer + decoded) & 0xf;
  decoded++;
  //IES_DECODE_U16(trackingareaidentitylist->tac, *(buffer + decoded));
  IES_DECODE_U16(buffer, decoded, trackingareaidentitylist->tac);
#if defined (NAS_DEBUG)
  dump_tracking_area_identity_list_xml(trackingareaidentitylist, iei);
#endif
  return decoded;
}
int decode_authentication_failure_parameter(AuthenticationFailureParameter *authenticationfailureparameter, uint8_t iei, uint8_t *buffer, uint32_t len)
{
  int decoded = 0;
  uint8_t ielen = 0;
  int decode_result;

  if (iei > 0) {
    CHECK_IEI_DECODER(iei, *buffer);
    decoded++;
  }

  ielen = *(buffer + decoded);
  decoded++;
  CHECK_LENGTH_DECODER(len - decoded, ielen);

  if ((decode_result = decode_octet_string(&authenticationfailureparameter->auts, ielen, buffer + decoded, len - decoded)) < 0)
    return decode_result;
  else
    decoded += decode_result;

#if defined (NAS_DEBUG)
  dump_authentication_failure_parameter_xml(authenticationfailureparameter, iei);
#endif
  return decoded;
}
int
decode_pdn_address (
  PdnAddress * pdnaddress,
  uint8_t iei,
  uint8_t * buffer,
  uint32_t len)
{
  int                                     decoded = 0;
  uint8_t                                 ielen = 0;
  int                                     decode_result;

  if (iei > 0) {
    CHECK_IEI_DECODER (iei, *buffer);
    decoded++;
  }

  ielen = *(buffer + decoded);
  decoded++;
  CHECK_LENGTH_DECODER (len - decoded, ielen);
  pdnaddress->pdntypevalue = *(buffer + decoded) & 0x7;
  decoded++;

  if ((decode_result = decode_octet_string (&pdnaddress->pdnaddressinformation, ielen - 1, buffer + decoded, len - decoded)) < 0)
    return decode_result;
  else
    decoded += decode_result;

#if NAS_DEBUG
  dump_pdn_address_xml (pdnaddress, iei);
#endif
  return decoded;
}
int
decode_ms_network_capability (
  MsNetworkCapability * msnetworkcapability,
  uint8_t iei,
  uint8_t * buffer,
  uint32_t len)
{
  int                                     decoded = 0;
  uint8_t                                 ielen = 0;
  int                                     decode_result;

  if (iei > 0) {
    CHECK_IEI_DECODER (iei, *buffer);
    decoded++;
  }

  ielen = *(buffer + decoded);
  decoded++;
  CHECK_LENGTH_DECODER (len - decoded, ielen);

  if ((decode_result = decode_octet_string (&msnetworkcapability->msnetworkcapabilityvalue, ielen, buffer + decoded, len - decoded)) < 0)
    return decode_result;
  else
    decoded += decode_result;

#if NAS_DEBUG
  dump_ms_network_capability_xml (msnetworkcapability, iei);
#endif
  return decoded;
}
int
decode_eps_network_feature_support (
  EpsNetworkFeatureSupport * epsnetworkfeaturesupport,
  uint8_t iei,
  uint8_t * buffer,
  uint32_t len)
{
  int                                     decoded = 0;
  uint8_t                                 ielen = 0;

  if (iei > 0) {
    CHECK_IEI_DECODER (iei, *buffer);
    decoded++;
  }

  ielen = *(buffer + decoded);
  decoded++;
  CHECK_LENGTH_DECODER (len - decoded, ielen);
  *epsnetworkfeaturesupport = *buffer & 0x1;
  decoded++;
#if NAS_DEBUG
  dump_eps_network_feature_support_xml (epsnetworkfeaturesupport, iei);
#endif
  return decoded;
}
int decode_esm_message_container(EsmMessageContainer *esmmessagecontainer, uint8_t iei, uint8_t *buffer, uint32_t len)
{
    int decoded = 0;
    int decode_result;
    uint16_t ielen;

    LOG_FUNC_IN;

    if (iei > 0) {
        CHECK_IEI_DECODER(iei, *buffer);
        decoded++;
    }

    DECODE_LENGTH_U16(buffer + decoded, ielen, decoded);

    CHECK_LENGTH_DECODER(len - decoded, ielen);


    if ((decode_result = decode_octet_string(&esmmessagecontainer->esmmessagecontainercontents, ielen, buffer + decoded, len - decoded)) < 0) {
        LOG_FUNC_RETURN(decode_result);
    } else {
        decoded += decode_result;
    }

#if defined (NAS_DEBUG)
    dump_esm_message_container_xml(esmmessagecontainer, iei);
#endif
    LOG_FUNC_RETURN(decoded);
}
int decode_nas_message_container(NasMessageContainer *nasmessagecontainer, uint8_t iei, uint8_t *buffer, uint32_t len)
{
  int decoded = 0;
  uint8_t ielen = 0;
  int decode_result;

  if (iei > 0) {
    CHECK_IEI_DECODER(iei, *buffer);
    decoded++;
  }

  ielen = *(buffer + decoded);
  decoded++;
  CHECK_LENGTH_DECODER(len - decoded, ielen);

  if ((decode_result = decode_octet_string(&nasmessagecontainer->nasmessagecontainercontents, ielen, buffer + decoded, len - decoded)) < 0)
    return decode_result;
  else
    decoded += decode_result;

#if defined (NAS_DEBUG)
  dump_nas_message_container_xml(nasmessagecontainer, iei);
#endif
  return decoded;
}
int decode_quality_of_service(QualityOfService *qualityofservice, uint8_t iei, uint8_t *buffer, uint32_t len)
{
    int decoded = 0;
    uint8_t ielen = 0;
    if (iei > 0)
    {
        CHECK_IEI_DECODER(iei, *buffer);
        decoded++;
    }
    ielen = *(buffer + decoded);
    decoded++;
    CHECK_LENGTH_DECODER(len - decoded, ielen);
    qualityofservice->delayclass = (*(buffer + decoded) >> 3) & 0x7;
    qualityofservice->reliabilityclass = *(buffer + decoded) & 0x7;
    decoded++;
    qualityofservice->peakthroughput = (*(buffer + decoded) >> 4) & 0xf;
    qualityofservice->precedenceclass = *(buffer + decoded) & 0x7;
    decoded++;
    qualityofservice->meanthroughput = *(buffer + decoded) & 0x1f;
    decoded++;
    qualityofservice->trafficclass = (*(buffer + decoded) >> 5) & 0x7;
    qualityofservice->deliveryorder = (*(buffer + decoded) >> 3) & 0x3;
    qualityofservice->deliveryoferroneoussdu = *(buffer + decoded) & 0x7;
    decoded++;
    qualityofservice->maximumsdusize = *(buffer + decoded);
    decoded++;
    qualityofservice->maximumbitrateuplink = *(buffer + decoded);
    decoded++;
    qualityofservice->maximumbitratedownlink = *(buffer + decoded);
    decoded++;
    qualityofservice->residualber = (*(buffer + decoded) >> 4) & 0xf;
    qualityofservice->sduratioerror = *(buffer + decoded) & 0xf;
    decoded++;
    qualityofservice->transferdelay = (*(buffer + decoded) >> 2) & 0x3f;
    qualityofservice->traffichandlingpriority = *(buffer + decoded) & 0x3;
    decoded++;
    qualityofservice->guaranteedbitrateuplink = *(buffer + decoded);
    decoded++;
    qualityofservice->guaranteedbitratedownlink = *(buffer + decoded);
    decoded++;
    qualityofservice->signalingindication = (*(buffer + decoded) >> 4) & 0x1;
    qualityofservice->sourcestatisticsdescriptor = *(buffer + decoded) & 0xf;
    decoded++;
#if defined (NAS_DEBUG)
    dump_quality_of_service_xml(qualityofservice, iei);
#endif
    return decoded;
}
int decode_traffic_flow_template(TrafficFlowTemplate *trafficflowtemplate, uint8_t iei, uint8_t *buffer, uint32_t len)
{
    int decoded = 0;
    int decoded_result = 0;
    uint8_t ielen = 0;

    if (iei > 0)
    {
        CHECK_IEI_DECODER(iei, *buffer);
        decoded++;
    }
    ielen = *(buffer + decoded);
    decoded++;
    CHECK_LENGTH_DECODER(len - decoded, ielen);
    trafficflowtemplate->tftoperationcode = (*(buffer + decoded) >> 5) & 0x7;
    trafficflowtemplate->ebit = (*(buffer + decoded) >> 4) & 0x1;
    trafficflowtemplate->numberofpacketfilters = *(buffer + decoded) & 0xf;
    decoded++;

    /* Decoding packet filter list */
    if (trafficflowtemplate->tftoperationcode == TRAFFIC_FLOW_TEMPLATE_OPCODE_DELETE_PACKET)
    {
	decoded_result = decode_traffic_flow_template_delete_packet(&trafficflowtemplate->packetfilterlist.deletepacketfilter, trafficflowtemplate->numberofpacketfilters, (buffer + decoded), len - decoded);
    }
    else if (trafficflowtemplate->tftoperationcode == TRAFFIC_FLOW_TEMPLATE_OPCODE_CREATE)
    {
	decoded_result = decode_traffic_flow_template_create_tft(&trafficflowtemplate->packetfilterlist.createtft, trafficflowtemplate->numberofpacketfilters, (buffer + decoded), len - decoded);
    }
    else if (trafficflowtemplate->tftoperationcode == TRAFFIC_FLOW_TEMPLATE_OPCODE_ADD_PACKET)
    {
	decoded_result = decode_traffic_flow_template_add_packet(&trafficflowtemplate->packetfilterlist.addpacketfilter, trafficflowtemplate->numberofpacketfilters, (buffer + decoded), len - decoded);
    }
    else if (trafficflowtemplate->tftoperationcode == TRAFFIC_FLOW_TEMPLATE_OPCODE_REPLACE_PACKET)
    {
	decoded_result = decode_traffic_flow_template_replace_packet(&trafficflowtemplate->packetfilterlist.replacepacketfilter, trafficflowtemplate->numberofpacketfilters, (buffer + decoded), len - decoded);
    }

#if defined (NAS_DEBUG)
    dump_traffic_flow_template_xml(trafficflowtemplate, iei);
#endif
    if (decoded_result < 0) {
        return decoded_result;
    }
    return (decoded + decoded_result);
}
int
decode_mobile_station_classmark_2 (
  MobileStationClassmark2 * mobilestationclassmark2,
  uint8_t iei,
  uint8_t * buffer,
  uint32_t len)
{
  int                                     decoded = 0;
  uint8_t                                 ielen = 0;

  if (iei > 0) {
    CHECK_IEI_DECODER (iei, *buffer);
    decoded++;
  }

  ielen = *(buffer + decoded);
  decoded++;
  CHECK_LENGTH_DECODER (len - decoded, ielen);
  mobilestationclassmark2->revisionlevel = (*(buffer + decoded) >> 5) & 0x3;
  mobilestationclassmark2->esind = (*(buffer + decoded) >> 4) & 0x1;
  mobilestationclassmark2->a51 = (*(buffer + decoded) >> 3) & 0x1;
  mobilestationclassmark2->rfpowercapability = *(buffer + decoded) & 0x7;
  decoded++;
  mobilestationclassmark2->pscapability = (*(buffer + decoded) >> 6) & 0x1;
  mobilestationclassmark2->ssscreenindicator = (*(buffer + decoded) >> 4) & 0x3;
  mobilestationclassmark2->smcapability = (*(buffer + decoded) >> 3) & 0x1;
  mobilestationclassmark2->vbs = (*(buffer + decoded) >> 2) & 0x1;
  mobilestationclassmark2->vgcs = (*(buffer + decoded) >> 1) & 0x1;
  mobilestationclassmark2->fc = *(buffer + decoded) & 0x1;
  decoded++;
  mobilestationclassmark2->cm3 = (*(buffer + decoded) >> 7) & 0x1;
  mobilestationclassmark2->lcsvacap = (*(buffer + decoded) >> 5) & 0x1;
  mobilestationclassmark2->ucs2 = (*(buffer + decoded) >> 4) & 0x1;
  mobilestationclassmark2->solsa = (*(buffer + decoded) >> 3) & 0x1;
  mobilestationclassmark2->cmsp = (*(buffer + decoded) >> 2) & 0x1;
  mobilestationclassmark2->a53 = (*(buffer + decoded) >> 1) & 0x1;
  mobilestationclassmark2->a52 = *(buffer + decoded) & 0x1;
  decoded++;
#if NAS_DEBUG
  dump_mobile_station_classmark_2_xml (mobilestationclassmark2, iei);
#endif
  return decoded;
}
int decode_ue_network_capability(UeNetworkCapability *uenetworkcapability, uint8_t iei, uint8_t *buffer, uint32_t len)
{
    int decoded = 0;
    uint8_t ielen = 0;
    if (iei > 0)
    {
        CHECK_IEI_DECODER(iei, *buffer);
        decoded++;
    }
    DECODE_U8(buffer + decoded, ielen, decoded);

    memset(uenetworkcapability, 0, sizeof(UeNetworkCapability));

    LOG_TRACE(INFO, "decode_ue_network_capability len = %d",ielen);
    CHECK_LENGTH_DECODER(len - decoded, ielen);
    uenetworkcapability->eea = *(buffer + decoded);
    decoded++;
    uenetworkcapability->eia = *(buffer + decoded);
    decoded++;

    /* Parts below not mandatory and may not be present */
    if (ielen > 2) {
        uenetworkcapability->uea = *(buffer + decoded);
        decoded++;

        if (ielen > 3) {
            uenetworkcapability->ucs2 = (*(buffer + decoded) >> 7) & 0x1;
            uenetworkcapability->uia = *(buffer + decoded) & 0x7f;
            decoded++;
            uenetworkcapability->umts_present =1;
            LOG_TRACE(INFO, "uenetworkcapability decoded UMTS\n");

            if (ielen > 4) {
                uenetworkcapability->spare = (*(buffer + decoded) >> 5) & 0x7;
                uenetworkcapability->csfb  = (*(buffer + decoded) >> 4) & 0x1;
                uenetworkcapability->lpp   = (*(buffer + decoded) >> 3) & 0x1;
                uenetworkcapability->lcs   = (*(buffer + decoded) >> 2) & 0x1;
                uenetworkcapability->srvcc = (*(buffer + decoded) >> 1) & 0x1;
                uenetworkcapability->nf    = *(buffer + decoded) & 0x1;
                decoded++;
                uenetworkcapability->gprs_present =1;
                LOG_TRACE(INFO, "uenetworkcapability decoded GPRS\n");
            }
int decode_packet_flow_identifier(PacketFlowIdentifier *packetflowidentifier, uint8_t iei, uint8_t *buffer, uint32_t len)
{
  int decoded = 0;
  uint8_t ielen = 0;

  if (iei > 0) {
    CHECK_IEI_DECODER(iei, *buffer);
    decoded++;
  }

  ielen = *(buffer + decoded);
  decoded++;
  CHECK_LENGTH_DECODER(len - decoded, ielen);
  *packetflowidentifier = *buffer & 0x7f;
  decoded++;
#if defined (NAS_DEBUG)
  dump_packet_flow_identifier_xml(packetflowidentifier, iei);
#endif
  return decoded;
}
int
decode_apn_aggregate_maximum_bit_rate (
  ApnAggregateMaximumBitRate * apnaggregatemaximumbitrate,
  uint8_t iei,
  uint8_t * buffer,
  uint32_t len)
{
  int                                     decoded = 0;
  uint8_t                                 ielen = 0;

  if (iei > 0) {
    CHECK_IEI_DECODER (iei, *buffer);
    decoded++;
  }

  ielen = *(buffer + decoded);
  decoded++;
  CHECK_LENGTH_DECODER (len - decoded, ielen);
  apnaggregatemaximumbitrate->apnambrfordownlink = *(buffer + decoded);
  decoded++;
  apnaggregatemaximumbitrate->apnambrforuplink = *(buffer + decoded);
  decoded++;

  if (ielen >= 4) {
    apnaggregatemaximumbitrate->apnambrfordownlink_extended = *(buffer + decoded);
    decoded++;
    apnaggregatemaximumbitrate->apnambrforuplink_extended = *(buffer + decoded);
    decoded++;

    if (ielen >= 6) {
      apnaggregatemaximumbitrate->apnambrfordownlink_extended2 = *(buffer + decoded);
      decoded++;
      apnaggregatemaximumbitrate->apnambrforuplink_extended2 = *(buffer + decoded);
      decoded++;
    }
  }
#if NAS_DEBUG
  dump_apn_aggregate_maximum_bit_rate_xml (apnaggregatemaximumbitrate, iei);
#endif
  return decoded;
}
int decode_eps_quality_of_service(EpsQualityOfService *epsqualityofservice, uint8_t iei, uint8_t *buffer, uint32_t len)
{
  int decoded = 0;
  uint8_t ielen = 0;

  if (iei > 0) {
    CHECK_IEI_DECODER(iei, *buffer);
    decoded++;
  }

  ielen = *(buffer + decoded);
  decoded++;
  CHECK_LENGTH_DECODER(len - decoded, ielen);
  epsqualityofservice->qci = *(buffer + decoded);
  decoded++;

  if ( ielen > 2 + (iei > 0) ? 1 : 0 ) {
    /* bitRates is present */
    epsqualityofservice->bitRatesPresent = 1;
    decoded += decode_eps_qos_bit_rates(&epsqualityofservice->bitRates,
                                        buffer + decoded);
  } else {
    /* bitRates is not present */
    epsqualityofservice->bitRatesPresent = 0;
  }

  if ( ielen > 6 + (iei > 0) ? 1 : 0 ) {
    /* bitRatesExt is present */
    epsqualityofservice->bitRatesExtPresent = 1;
    decoded += decode_eps_qos_bit_rates(&epsqualityofservice->bitRatesExt,
                                        buffer + decoded);
  } else {
    /* bitRatesExt is not present */
    epsqualityofservice->bitRatesExtPresent = 0;
  }

#if defined (NAS_DEBUG)
  dump_eps_quality_of_service_xml(epsqualityofservice, iei);
#endif
  return decoded;
}
Example #19
0
int decode_cli(Cli *cli, uint8_t iei, uint8_t *buffer, uint32_t len)
{
    int decoded = 0;
    uint8_t ielen = 0;
    int decode_result;
    if (iei > 0)
    {
        CHECK_IEI_DECODER(iei, *buffer);
        decoded++;
    }
    ielen = *(buffer + decoded);
    decoded++;
    CHECK_LENGTH_DECODER(len - decoded, ielen);
    if ((decode_result = decode_octet_string(&cli->clivalue, ielen, buffer + decoded, len - decoded)) < 0)
        return decode_result;
    else
        decoded += decode_result;
#if defined (NAS_DEBUG)
    dump_cli_xml(cli, iei);
#endif
    return decoded;
}