Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 51 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ for _, i := range cpdrIE.ChildIEs {

#### List of supported IEs

IEs are implemented in conformance with TS 29.244 V16.7.0 (2021-04). The word "supported" in the table below means that the constructor and helper method for the IE are implemented in this library. As described in the previous section, you can still create an IE of any type even if it is not supported or missing in the table.
IEs are implemented in conformance with TS 29.244 V17.5.0 (2022-07). The word "supported" in the table below means that the constructor and helper method for the IE are implemented in this library. As described in the previous section, you can still create an IE of any type even if it is not supported or missing in the table.

| IE Type | Information elements | Supported? |
| -------------- | -------------------------------------------------------------------------- | ---------- |
Expand Down Expand Up @@ -800,7 +800,56 @@ IEs are implemented in conformance with TS 29.244 V16.7.0 (2021-04). The word "s
| 269 | Validity Timer | Yes |
| 270 | Redundant Transmission Forwarding Parameters | Yes |
| 271 | Transport Delay Reporting | Yes |
| 272 to 32767 | _(For future use)_ | - |
| 272 | Partial Failure Information | Yes |
| 274 | Offending IE Information | Yes |
| 275 | RAT Type | Yes |
| 276 | L2TP Tunnel Information | Yes |
| 277 | L2TP Session Information | Yes |
| 278 | L2TP User Authentication IE | No |
| 279 | Created L2TP Session | Yes |
| 280 | LNS Address | Yes |
| 281 | Tunnel Preference | Yes |
| 282 | Calling Number | Yes |
| 283 | Called Number | Yes |
| 284 | L2TP Session Indications | Yes |
| 285 | DNS Server Address | Yes |
| 286 | NBNS Server Address | Yes |
| 287 | Maximum Receive Unit | Yes |
| 288 | Thresholds | Yes |
| 289 | Steering Mode Indicator | Yes |
| 290 | FPCP Session Change Info | Yes |
| 291 | Group ID | Yes |
| 292 | CP IP Address | Yes |
| 293 | IP Adress and Port number Replacement | Yes |
| 294 | DNS Query Filter | Yes |
| 295 | Direct Reporting Filter | Yes |
| 296 | Event Notification URI | Yes |
| 297 | Notification Correlation ID | Yes |
| 298 | Reporting Flags | Yes |
| 299 | Predefined Rules Name | Yes |
| 300 | MBS Session N4mb Control Information | Yes |
| 301 | MBS Multicast Parameters | Yes |
| 302 | Add MBS Unicast Parameters | Yes |
| 303 | MBS Session N4mb Information | Yes |
| 304 | Remove MBS Unicast Parameters | Yes |
| 305 | MBS Session Identifier | Yes |
| 306 | Multicast Transport Information | Yes |
| 307 | MBNS4mbReq-Flags | Yes |
| 308 | Local Ingress Tunnel | Yes |
| 309 | MBS Unicast Parameters ID | Yes |
| 310 | MBS Session N4 Control Information | Yes |
| 311 | MBS Session N4 Information | Yes |
| 312 | MBSN4Resp-Flags | Yes |
| 313 | Tunnel Password | Yes |
| 314 | Area Session ID | Yes |
| 315 | Peer UP Restart Report | Yes |
| 316 | DSCP to PPI Control Information | Yes |
| 317 | DSCP to PPI Mapping Information | Yes |
| 318 | PFCPSDRsp-Flags | Yes |
| 319 | Qer Indications | Yes |
| 320 | Vendor-Specific Node Report Type | No |
| 321 | Configured Time Domain | Yes |
| 322 to 32767 | _(For future use)_ | - |
| 32768 to 65535 | Reserved for vendor specific IEs | - |

## Author(s)
Expand Down
56 changes: 36 additions & 20 deletions ie/access-availability-control-information.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,44 +10,60 @@ func NewAccessAvailabilityControlInformation(info *IE) *IE {
}

// AccessAvailabilityControlInformation returns the IEs above AccessAvailabilityControlInformation if the type of IE matches.
func (i *IE) AccessAvailabilityControlInformation() ([]*IE, error) {
func (i *IE) AccessAvailabilityControlInformation() (*AccessAvailabilityControlInformationFields, error) {
switch i.Type {
case AccessAvailabilityControlInformation:
return ParseMultiIEs(i.Payload)
return ParseAccessAvailabilityControlInformationFields(i.Payload)
case CreateSRR:
ies, err := i.CreateSRR()
if err != nil {
return nil, err
}
for _, x := range ies {
if x.Type == AccessAvailabilityControlInformation {
return x.AccessAvailabilityControlInformation()
}
if ies.AccessAvailabilityControlInformation != nil {
return ies.AccessAvailabilityControlInformation, nil
}
return nil, ErrIENotFound
case UpdateSRR:
ies, err := i.UpdateSRR()
if err != nil {
return nil, err
}
for _, x := range ies {
if x.Type == AccessAvailabilityControlInformation {
return x.AccessAvailabilityControlInformation()
}
if ies.AccessAvailabilityControlInformation != nil {
return ies.AccessAvailabilityControlInformation, nil
}
return nil, ErrIENotFound
case SessionReport:
ies, err := i.SessionReport()
if err != nil {
return nil, err
default:
return nil, &InvalidTypeError{Type: i.Type}
}
}

// AccessAvailabilityControlInformationFields is a set of fields in CreateSSR IE.
//
// The contained fields are of type struct, as they are too complex to handle with
// existing (standard) types in Go.
type AccessAvailabilityControlInformationFields struct {
RequestedAccessAvailabilityInformation uint8
}

func ParseAccessAvailabilityControlInformationFields(b []byte) (*AccessAvailabilityControlInformationFields, error) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing godoc comment


// Parse all IES heres
Comment on lines +49 to +50
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Parse all IES heres

typo, but in the first place I don't think we need this comment, as it's obvious

ies, err := ParseMultiIEs(b)
if err != nil {
return nil, err
}
a := &AccessAvailabilityControlInformationFields{}
for _, ie := range ies {
if ie == nil {
continue
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, each XxxFields structure should have IEs or ExtraIEs that contains all the IEs that did not match the predefined types. This helps users access the IEs that we don't explicitly support (e.g., those added in the next spec update won't necessarily be added in structure in real-time).

}
for _, x := range ies {
if x.Type == AccessAvailabilityControlInformation {
return x.AccessAvailabilityControlInformation()
if ie.Type == RequestedAccessAvailabilityInformation {
v, err := ie.RequestedAccessAvailabilityInformation()
if err != nil {
return a, err
}
a.RequestedAccessAvailabilityInformation = v
}
return nil, ErrIENotFound
default:
return nil, &InvalidTypeError{Type: i.Type}
}
return a, nil
}
8 changes: 1 addition & 7 deletions ie/access-availability-information.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,7 @@ func (i *IE) AccessAvailabilityInformation() (uint8, error) {
if err != nil {
return 0, err
}

for _, x := range ies {
if x.Type == AccessAvailabilityInformation {
return x.AccessAvailabilityInformation()
}
}
return 0, ErrIENotFound
return ies.AccessAvailabilityInformation, nil
default:
return 0, &InvalidTypeError{Type: i.Type}
}
Expand Down
51 changes: 49 additions & 2 deletions ie/access-availability-report.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,57 @@ func NewAccessAvailabilityReport(info *IE) *IE {
}

// AccessAvailabilityReport returns the IEs above AccessAvailabilityReport if the type of IE matches.
func (i *IE) AccessAvailabilityReport() ([]*IE, error) {
func (i *IE) AccessAvailabilityReport() (*AccessAvailabilityReportFields, error) {
if i.Type != AccessAvailabilityReport {
return nil, &InvalidTypeError{Type: i.Type}
}
// Check if the ie.Parse have called or not
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In which kind of situation it is already parsed and it is not? Clarifying that in the comment would definitely help devs in the future.

if len(i.ChildIEs) > 0 {
p := &AccessAvailabilityReportFields{}
if err := p.ParseIEs(i.ChildIEs...); err != nil {
return p, err
}
return p, nil
}
// If the ChildIEs not already parsed
return ParseAccessAvailabilityReportFields(i.Payload)
}

// AccessAvailabilityReportFields is a set of fields in AccessAvailabilityReport IE.
//
// The contained fields are of type struct, as they are too complex to handle with
// existing (standard) types in Go.
type AccessAvailabilityReportFields struct {
AccessAvailabilityInformation uint8
}

// ParseAccessAvailabilityReportFields returns the IEs above AccessAvailabilityReport
func ParseAccessAvailabilityReportFields(b []byte) (*AccessAvailabilityReportFields, error) {
ies, err := ParseMultiIEs(b)
if err != nil {
return nil, err
}
c := &AccessAvailabilityReportFields{}
if err := c.ParseIEs(ies...); err != nil {
return c, err
}

return ParseMultiIEs(i.Payload)
return c, nil
}

// ParseIEs will iterator over all childs IE to avoid to use Parse or ParseMultiIEs any time we iterate in IE
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// ParseIEs will iterator over all childs IE to avoid to use Parse or ParseMultiIEs any time we iterate in IE
// ParseIEs will iterate over all childs IE to avoid to use Parse or ParseMultiIEs any time we iterate in IE

typo, but is it necessary for this function to be exported?

func (s *AccessAvailabilityReportFields) ParseIEs(ies ...*IE) error {
for _, i := range ies {
if i == nil {
continue
}
if i.Type == AccessAvailabilityInformation {
v, err := i.AccessAvailabilityInformation()
if err != nil {
return nil
}
s.AccessAvailabilityInformation = v
}
}
return nil
}
12 changes: 4 additions & 8 deletions ie/activate-predefined-rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,17 @@ func (i *IE) ActivatePredefinedRules() (string, error) {
if err != nil {
return "", err
}
for _, x := range ies {
if x.Type == ActivatePredefinedRules {
return x.ActivatePredefinedRules()
}
if len(ies.ActivatePredefinedRules) > 0 {
return ies.ActivatePredefinedRules, nil
Comment on lines +22 to +23
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We return "" by default, so this check doesn't really do nothing. See the top-level comment for nil vs empty value handling

}
return "", ErrIENotFound
case UpdatePDR:
ies, err := i.UpdatePDR()
if err != nil {
return "", err
}
for _, x := range ies {
if x.Type == ActivatePredefinedRules {
return x.ActivatePredefinedRules()
}
if len(ies.ActivatePredefinedRules) > 0 {
return ies.ActivatePredefinedRules, nil
}
return "", ErrIENotFound
default:
Expand Down
12 changes: 4 additions & 8 deletions ie/activation-time.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,17 @@ func (i *IE) ActivationTime() (time.Time, error) {
if err != nil {
return time.Time{}, err
}
for _, x := range ies {
if x.Type == ActivationTime {
return x.ActivationTime()
}
if !ies.ActivationTime.IsZero() {
return ies.ActivationTime, nil
}
return time.Time{}, ErrIENotFound
case UpdatePDR:
ies, err := i.UpdatePDR()
if err != nil {
return time.Time{}, err
}
for _, x := range ies {
if x.Type == ActivationTime {
return x.ActivationTime()
}
if !ies.ActivationTime.IsZero() {
return ies.ActivationTime, nil
}
return time.Time{}, ErrIENotFound
default:
Expand Down
115 changes: 115 additions & 0 deletions ie/add-mbs-unicast-parameters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package ie

// NewAddMBSUnicastParameters creates a new AbsMBSUnicastParameters IE.
func NewAddMBSUnicastParameters(ies ...*IE) *IE {
return newGroupedIE(AddMBSUnicastParameters, 0, ies...)
}

// AddMBSUnicastParameters returns the IEs above AddMBSUnicastParameters if the type of IE matches.
func (i *IE) AddMBSUnicastParameters() (*AddMBSUnicastParametersFields, error) {
switch i.Type {
case AddMBSUnicastParameters:
return ParseAddMBSUnicastParametersFields(i.Payload)
case CreateFAR:
ies, err := i.CreateFAR()
if err != nil {
return nil, err
}
for _, i := range ies.AddMBSUnicastParameters {
if i == nil {
continue
}
return i, nil
}
return nil, ErrIENotFound
case UpdateFAR:
ies, err := i.UpdateFAR()
if err != nil {
return nil, err
}
for _, i := range ies.AddMBSUnicastParameters {
if i == nil {
continue
}
return i, nil
}
return nil, ErrIENotFound
default:
return nil, &InvalidTypeError{Type: i.Type}
}
}

// AddMBSUnicastParametersFields is a set of fields in AddMBSUnicastParameters IE.
//
// The contained fields are of type struct, as they are too complex to handle with
// existing (standard) types in Go.
type AddMBSUnicastParametersFields struct {
DestinationInterface uint8
MBSUnicastParametersID uint16
NetworkInstance string
OuterHeaderCreation *OuterHeaderCreationFields
TransportLevelMarking uint16
DestinationInterfaceType uint8
}

// ParseAddMBSUnicastParametersFields returns the IEs above AddMBSUnicastParameters.
func ParseAddMBSUnicastParametersFields(b []byte) (*AddMBSUnicastParametersFields, error) {
ies, err := ParseMultiIEs(b)
if err != nil {
return nil, err
}
f := &AddMBSUnicastParametersFields{}
if err := f.ParseIEs(ies...); err != nil {
return f, err
}
return f, nil
}

// ParseIEs will iterator over all childs IE to avoid to use Parse or ParseMultiIEs any time we iterate in IE
func (a *AddMBSUnicastParametersFields) ParseIEs(ies ...*IE) error {
for _, ie := range ies {
if ie == nil {
continue
}

switch ie.Type {
case DestinationInterface:
dest, err := ie.DestinationInterface()
if err != nil {
return err
}
a.DestinationInterface = dest
case MBSUnicastParametersID:
v, err := ie.MBSUnicastParametersID()
if err != nil {
return err
}
a.MBSUnicastParametersID = v
case NetworkInstance:
v, err := ie.NetworkInstance()
if err != nil {
return err
}
a.NetworkInstance = v
case OuterHeaderCreation:
creation, err := ie.OuterHeaderCreation()
if err != nil {
return err
}
a.OuterHeaderCreation = creation
case TransportLevelMarking:
transport, err := ie.TransportLevelMarking()
if err != nil {
return err
}
a.TransportLevelMarking = transport
case TGPPInterfaceType:
tgppinterface, err := ie.TGPPInterfaceType()
if err != nil {
return err
}
a.DestinationInterfaceType = tgppinterface
}
}
return nil
}
Loading