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_tracking_area_identity(TrackingAreaIdentity *trackingareaidentity, uint8_t iei, uint8_t *buffer, uint32_t len) { int decoded = 0; if (iei > 0) { CHECK_IEI_DECODER(iei, *buffer); decoded++; } trackingareaidentity->mccdigit2 = (*(buffer + decoded) >> 4) & 0xf; trackingareaidentity->mccdigit1 = *(buffer + decoded) & 0xf; decoded++; trackingareaidentity->mncdigit3 = (*(buffer + decoded) >> 4) & 0xf; trackingareaidentity->mccdigit3 = *(buffer + decoded) & 0xf; decoded++; trackingareaidentity->mncdigit2 = (*(buffer + decoded) >> 4) & 0xf; trackingareaidentity->mncdigit1 = *(buffer + decoded) & 0xf; decoded++; //IES_DECODE_U16(trackingareaidentity->tac, *(buffer + decoded)); IES_DECODE_U16(buffer, decoded, trackingareaidentity->tac); #if defined (NAS_DEBUG) dump_tracking_area_identity_xml(trackingareaidentity, iei); #endif return decoded; }
int decode_short_mac(ShortMac *shortmac, uint8_t iei, uint8_t *buffer, uint32_t len) { int decoded = 0; if (iei > 0) { CHECK_IEI_DECODER(iei, *buffer); decoded++; } //IES_DECODE_U16(*shortmac, *(buffer + decoded)); IES_DECODE_U16(buffer, decoded, *shortmac); #if defined (NAS_DEBUG) dump_short_mac_xml(shortmac, iei); #endif return decoded; }
int decode_location_area_identification(LocationAreaIdentification *locationareaidentification, uint8_t iei, uint8_t *buffer, uint32_t len) { int decoded = 0; if (iei > 0) { CHECK_IEI_DECODER(iei, *buffer); decoded++; } locationareaidentification->mccdigit2 = (*(buffer + decoded) >> 4) & 0xf; locationareaidentification->mccdigit1 = *(buffer + decoded) & 0xf; decoded++; locationareaidentification->mncdigit3 = (*(buffer + decoded) >> 4) & 0xf; locationareaidentification->mccdigit3 = *(buffer + decoded) & 0xf; decoded++; locationareaidentification->mncdigit2 = (*(buffer + decoded) >> 4) & 0xf; locationareaidentification->mncdigit1 = *(buffer + decoded) & 0xf; decoded++; //IES_DECODE_U16(locationareaidentification->lac, *(buffer + decoded)); IES_DECODE_U16(buffer, decoded, locationareaidentification->lac); #if defined (NAS_DEBUG) dump_location_area_identification_xml(locationareaidentification, iei); #endif return decoded; }
static int decode_traffic_flow_template_packet_filters(PacketFilters* packetfilters, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len) { int decoded = 0, i, j; for (i = 0; (i < nbpacketfilters); i++) { if (len - decoded <= 0) { /* Mismatch between the number of packet filters subfield, * and the number of packet filters in the packet filter list */ return (TLV_DECODE_VALUE_DOESNT_MATCH); } /* Initialize the packet filter presence flag indicator */ (*packetfilters)[i].packetfilter.flags = 0; /* Packet filter direction */ (*packetfilters)[i].direction = *(buffer + decoded) >> 4; /* Packet filter identifier */ (*packetfilters)[i].identifier = *(buffer + decoded) & 0x0f; decoded++; /* Packet filter evaluation precedence */ IES_DECODE_U8(buffer, decoded, (*packetfilters)[i].eval_precedence); /* Length of the Packet filter contents field */ uint8_t pkflen; IES_DECODE_U8(buffer, decoded, pkflen); /* Packet filter contents */ int pkfstart = decoded; while (decoded - pkfstart < pkflen) { /* Packet filter component type identifier */ uint8_t component_type; IES_DECODE_U8(buffer, decoded, component_type); switch (component_type) { case TRAFFIC_FLOW_TEMPLATE_IPV4_REMOTE_ADDR: /* IPv4 remote address type */ (*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_IPV4_REMOTE_ADDR_FLAG; for (j = 0; j < TRAFFIC_FLOW_TEMPLATE_IPV4_ADDR_SIZE; j++) { (*packetfilters)[i].packetfilter.ipv4remoteaddr[j].addr = *(buffer + decoded); (*packetfilters)[i].packetfilter.ipv4remoteaddr[j].mask = *(buffer + decoded + TRAFFIC_FLOW_TEMPLATE_IPV4_ADDR_SIZE); decoded++; } decoded += TRAFFIC_FLOW_TEMPLATE_IPV4_ADDR_SIZE; break; case TRAFFIC_FLOW_TEMPLATE_IPV6_REMOTE_ADDR: /* IPv6 remote address type */ (*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_IPV6_REMOTE_ADDR_FLAG; for (j = 0; j < TRAFFIC_FLOW_TEMPLATE_IPV6_ADDR_SIZE; j++) { (*packetfilters)[i].packetfilter.ipv6remoteaddr[j].addr = *(buffer + decoded); (*packetfilters)[i].packetfilter.ipv6remoteaddr[j].mask = *(buffer + decoded + TRAFFIC_FLOW_TEMPLATE_IPV6_ADDR_SIZE); decoded++; } decoded += TRAFFIC_FLOW_TEMPLATE_IPV6_ADDR_SIZE; break; case TRAFFIC_FLOW_TEMPLATE_PROTOCOL_NEXT_HEADER: /* Protocol identifier/Next header type */ (*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_PROTOCOL_NEXT_HEADER_FLAG; IES_DECODE_U8(buffer, decoded, (*packetfilters)[i].packetfilter.protocolidentifier_nextheader); break; case TRAFFIC_FLOW_TEMPLATE_SINGLE_LOCAL_PORT: /* Single local port type */ (*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_SINGLE_LOCAL_PORT_FLAG; IES_DECODE_U16(buffer, decoded, (*packetfilters)[i].packetfilter.singlelocalport); break; case TRAFFIC_FLOW_TEMPLATE_LOCAL_PORT_RANGE: /* Local port range type */ (*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_LOCAL_PORT_RANGE_FLAG; IES_DECODE_U16(buffer, decoded, (*packetfilters)[i].packetfilter.localportrange.lowlimit); IES_DECODE_U16(buffer, decoded, (*packetfilters)[i].packetfilter.localportrange.highlimit); break; case TRAFFIC_FLOW_TEMPLATE_SINGLE_REMOTE_PORT: /* Single remote port type */ (*packetfilters)[i].packetfilter.flags |=TRAFFIC_FLOW_TEMPLATE_SINGLE_REMOTE_PORT_FLAG ; IES_DECODE_U16(buffer, decoded, (*packetfilters)[i].packetfilter.singleremoteport); break; case TRAFFIC_FLOW_TEMPLATE_REMOTE_PORT_RANGE: /* Remote port range type */ (*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_REMOTE_PORT_RANGE_FLAG; IES_DECODE_U16(buffer, decoded, (*packetfilters)[i].packetfilter.remoteportrange.lowlimit); IES_DECODE_U16(buffer, decoded, (*packetfilters)[i].packetfilter.remoteportrange.highlimit); break; case TRAFFIC_FLOW_TEMPLATE_SECURITY_PARAMETER_INDEX: /* Security parameter index type */ (*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_SECURITY_PARAMETER_INDEX_FLAG; IES_DECODE_U32(buffer, decoded, (*packetfilters)[i].packetfilter.securityparameterindex); break; case TRAFFIC_FLOW_TEMPLATE_TYPE_OF_SERVICE_TRAFFIC_CLASS: /* Type of service/Traffic class type */ (*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_TYPE_OF_SERVICE_TRAFFIC_CLASS_FLAG; IES_DECODE_U8(buffer, decoded, (*packetfilters)[i].packetfilter.typdeofservice_trafficclass.value); IES_DECODE_U8(buffer, decoded, (*packetfilters)[i].packetfilter.typdeofservice_trafficclass.mask); break; case TRAFFIC_FLOW_TEMPLATE_FLOW_LABEL: /* Flow label type */ (*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_FLOW_LABEL_FLAG; IES_DECODE_U24(buffer, decoded, (*packetfilters)[i].packetfilter.flowlabel); break; default: /* Packet filter component type identifier is not valid */ return (TLV_DECODE_UNEXPECTED_IEI); break; } } } if (len - decoded != 0) { /* Mismatch between the number of packet filters subfield, * and the number of packet filters in the packet filter list */ return (TLV_DECODE_VALUE_DOESNT_MATCH); } return decoded; }