int encode_short_mac ( ShortMac * shortmac, uint8_t iei, uint8_t * buffer, uint32_t len) { uint32_t encoded = 0; /* * Checking IEI and pointer */ CHECK_PDU_POINTER_AND_LENGTH_ENCODER (buffer, SHORT_MAC_MINIMUM_LENGTH, len); #if NAS_DEBUG dump_short_mac_xml (shortmac, iei); #endif if (iei > 0) { *buffer = iei; encoded++; } IES_ENCODE_U16 (buffer, encoded, *shortmac); return encoded; }
int encode_location_area_identification(LocationAreaIdentification *locationareaidentification, uint8_t iei, uint8_t *buffer, uint32_t len) { uint32_t encoded = 0; /* Checking IEI and pointer */ CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, LOCATION_AREA_IDENTIFICATION_MINIMUM_LENGTH, len); #if defined (NAS_DEBUG) dump_location_area_identification_xml(locationareaidentification, iei); #endif if (iei > 0) { *buffer = iei; encoded++; } *(buffer + encoded) = 0x00 | ((locationareaidentification->mccdigit2 & 0xf) << 4) | (locationareaidentification->mccdigit1 & 0xf); encoded++; *(buffer + encoded) = 0x00 | ((locationareaidentification->mncdigit3 & 0xf) << 4) | (locationareaidentification->mccdigit3 & 0xf); encoded++; *(buffer + encoded) = 0x00 | ((locationareaidentification->mncdigit2 & 0xf) << 4) | (locationareaidentification->mncdigit1 & 0xf); encoded++; IES_ENCODE_U16(buffer, encoded, locationareaidentification->lac); return encoded; }
int encode_tracking_area_identity_list(TrackingAreaIdentityList *trackingareaidentitylist, uint8_t iei, uint8_t *buffer, uint32_t len) { uint8_t *lenPtr; uint32_t encoded = 0; /* Checking IEI and pointer */ CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, TRACKING_AREA_IDENTITY_LIST_MINIMUM_LENGTH, len); #if defined (NAS_DEBUG) dump_tracking_area_identity_list_xml(trackingareaidentitylist, iei); #endif if (iei > 0) { *buffer = iei; encoded++; } lenPtr = (buffer + encoded); encoded ++; *(buffer + encoded) = 0x00 | ((trackingareaidentitylist->typeoflist & 0x3) << 5) | (trackingareaidentitylist->numberofelements & 0x1f); encoded++; *(buffer + encoded) = 0x00 | ((trackingareaidentitylist->mccdigit2 & 0xf) << 4) | (trackingareaidentitylist->mccdigit1 & 0xf); encoded++; *(buffer + encoded) = 0x00 | ((trackingareaidentitylist->mncdigit3 & 0xf) << 4) | (trackingareaidentitylist->mccdigit3 & 0xf); encoded++; *(buffer + encoded) = 0x00 | ((trackingareaidentitylist->mncdigit2 & 0xf) << 4) | (trackingareaidentitylist->mncdigit1 & 0xf); encoded++; IES_ENCODE_U16(buffer, encoded, trackingareaidentitylist->tac); *lenPtr = encoded - 1 - ((iei > 0) ? 1 : 0); return encoded; }
int encode_tracking_area_identity(TrackingAreaIdentity *trackingareaidentity, uint8_t iei, uint8_t *buffer, uint32_t len) { uint32_t encoded = 0; /* Checking IEI and pointer */ CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, TRACKING_AREA_IDENTITY_MINIMUM_LENGTH, len); #if defined (NAS_DEBUG) dump_tracking_area_identity_xml(trackingareaidentity, iei); #endif if (iei > 0) { *buffer = iei; encoded++; } *(buffer + encoded) = 0x00 | ((trackingareaidentity->mccdigit2 & 0xf) << 4) | (trackingareaidentity->mccdigit1 & 0xf); encoded++; *(buffer + encoded) = 0x00 | ((trackingareaidentity->mncdigit3 & 0xf) << 4) | (trackingareaidentity->mccdigit3 & 0xf); encoded++; *(buffer + encoded) = 0x00 | ((trackingareaidentity->mncdigit2 & 0xf) << 4) | (trackingareaidentity->mncdigit1 & 0xf); encoded++; IES_ENCODE_U16(buffer, encoded, trackingareaidentity->tac); return encoded; }
static int encode_traffic_flow_template_packet_filters(PacketFilters* packetfilters, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len) { int encoded = 0, i, j; for (i = 0; (i < nbpacketfilters) && (len - encoded > 0); i++) { if (len - encoded <= 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); } /* Packet filter identifier and direction */ IES_ENCODE_U8(buffer, encoded, (0x00 | ((*packetfilters)[i].direction << 4) | ((*packetfilters)[i].identifier))); /* Packet filter evaluation precedence */ IES_ENCODE_U8(buffer, encoded, (*packetfilters)[i].eval_precedence); /* Save address of the Packet filter contents field length */ uint8_t* pkflenPtr = buffer + encoded; encoded++; /* Packet filter contents */ int pkfstart = encoded; uint16_t flag = TRAFFIC_FLOW_TEMPLATE_IPV4_REMOTE_ADDR_FLAG; while (flag <= TRAFFIC_FLOW_TEMPLATE_FLOW_LABEL_FLAG) { switch ((*packetfilters)[i].packetfilter.flags & flag) { case TRAFFIC_FLOW_TEMPLATE_IPV4_REMOTE_ADDR_FLAG: /* IPv4 remote address type */ IES_ENCODE_U8(buffer, encoded, TRAFFIC_FLOW_TEMPLATE_IPV4_REMOTE_ADDR); for (j = 0; j < TRAFFIC_FLOW_TEMPLATE_IPV4_ADDR_SIZE; j++) { *(buffer + encoded) = (*packetfilters)[i].packetfilter.ipv4remoteaddr[j].addr; *(buffer + encoded + TRAFFIC_FLOW_TEMPLATE_IPV4_ADDR_SIZE) = (*packetfilters)[i].packetfilter.ipv4remoteaddr[j].mask; encoded++; } encoded += TRAFFIC_FLOW_TEMPLATE_IPV4_ADDR_SIZE; break; case TRAFFIC_FLOW_TEMPLATE_IPV6_REMOTE_ADDR_FLAG: /* IPv6 remote address type */ IES_ENCODE_U8(buffer, encoded, TRAFFIC_FLOW_TEMPLATE_IPV6_REMOTE_ADDR); for (j = 0; j < TRAFFIC_FLOW_TEMPLATE_IPV6_ADDR_SIZE; j++) { *(buffer + encoded) = (*packetfilters)[i].packetfilter.ipv6remoteaddr[j].addr; *(buffer + encoded + TRAFFIC_FLOW_TEMPLATE_IPV6_ADDR_SIZE) = (*packetfilters)[i].packetfilter.ipv6remoteaddr[j].mask; encoded++; } encoded += TRAFFIC_FLOW_TEMPLATE_IPV6_ADDR_SIZE; break; case TRAFFIC_FLOW_TEMPLATE_PROTOCOL_NEXT_HEADER_FLAG: /* Protocol identifier/Next header type */ IES_ENCODE_U8(buffer, encoded, TRAFFIC_FLOW_TEMPLATE_PROTOCOL_NEXT_HEADER); IES_ENCODE_U8(buffer, encoded, (*packetfilters)[i].packetfilter.protocolidentifier_nextheader); break; case TRAFFIC_FLOW_TEMPLATE_SINGLE_LOCAL_PORT_FLAG: /* Single local port type */ IES_ENCODE_U8(buffer, encoded, TRAFFIC_FLOW_TEMPLATE_SINGLE_LOCAL_PORT); IES_ENCODE_U16(buffer, encoded, (*packetfilters)[i].packetfilter.singlelocalport); break; case TRAFFIC_FLOW_TEMPLATE_LOCAL_PORT_RANGE_FLAG: /* Local port range type */ IES_ENCODE_U8(buffer, encoded, TRAFFIC_FLOW_TEMPLATE_LOCAL_PORT_RANGE); IES_ENCODE_U16(buffer, encoded, (*packetfilters)[i].packetfilter.localportrange.lowlimit); IES_ENCODE_U16(buffer, encoded, (*packetfilters)[i].packetfilter.localportrange.highlimit); break; case TRAFFIC_FLOW_TEMPLATE_SINGLE_REMOTE_PORT_FLAG: /* Single remote port type */ IES_ENCODE_U8(buffer, encoded, TRAFFIC_FLOW_TEMPLATE_SINGLE_REMOTE_PORT); IES_ENCODE_U16(buffer, encoded, (*packetfilters)[i].packetfilter.singleremoteport); break; case TRAFFIC_FLOW_TEMPLATE_REMOTE_PORT_RANGE_FLAG: /* Remote port range type */ IES_ENCODE_U8(buffer, encoded, TRAFFIC_FLOW_TEMPLATE_REMOTE_PORT_RANGE); IES_ENCODE_U16(buffer, encoded, (*packetfilters)[i].packetfilter.remoteportrange.lowlimit); IES_ENCODE_U16(buffer, encoded, (*packetfilters)[i].packetfilter.remoteportrange.highlimit); break; case TRAFFIC_FLOW_TEMPLATE_SECURITY_PARAMETER_INDEX_FLAG: /* Security parameter index type */ IES_ENCODE_U8(buffer, encoded, TRAFFIC_FLOW_TEMPLATE_SECURITY_PARAMETER_INDEX); IES_ENCODE_U32(buffer, encoded, (*packetfilters)[i].packetfilter.securityparameterindex); break; case TRAFFIC_FLOW_TEMPLATE_TYPE_OF_SERVICE_TRAFFIC_CLASS_FLAG: /* Type of service/Traffic class type */ IES_ENCODE_U8(buffer, encoded, TRAFFIC_FLOW_TEMPLATE_TYPE_OF_SERVICE_TRAFFIC_CLASS); IES_ENCODE_U8(buffer, encoded, (*packetfilters)[i].packetfilter.typdeofservice_trafficclass.value); IES_ENCODE_U8(buffer, encoded, (*packetfilters)[i].packetfilter.typdeofservice_trafficclass.mask); break; case TRAFFIC_FLOW_TEMPLATE_FLOW_LABEL_FLAG: /* Flow label type */ IES_ENCODE_U8(buffer, encoded, TRAFFIC_FLOW_TEMPLATE_FLOW_LABEL); IES_ENCODE_U24(buffer, encoded, (*packetfilters)[i].packetfilter.flowlabel & 0x000fffff); break; default: break; } flag = flag << 1; } /* Length of the Packet filter contents field */ *pkflenPtr = encoded - pkfstart; } return encoded; }