Mistake on this page?
Report an issue in GitHub or email us
MsgHeader.h
1 /*
2  * Copyright (c) 2021 ARM Limited
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef MSG_HEADER_H
19 #define MSG_HEADER_H
20 
21 #include "netsocket/nsapi_types.h"
22 
23 /**
24  * Allows iteration through the list of message headers received in the control parameter of the
25  * socket_sendto_control / socket_recvfrom_control methods.
26  *
27  * @par Members types
28  *
29  * MsgHeaderIterator works on the list which members are of type nsapi_msghdr_t or other types
30  * extending this struct. For example nsapi_pktinfo:
31  *
32  * @code
33  typedef struct nsapi_pktinfo {
34  nsapi_msghdr_t hdr;
35  nsapi_addr_t ipi_addr;
36  int ipi_ifindex;
37  void *network_interface;
38  } nsapi_pktinfo_t;
39  * @endcode
40  *
41  * There are two requirements for such structures to work well with MsgHeaderIterator.
42  * - First element needs to be of type nsapi_msghdr_t.
43  * - Value of the field len of the nsapi_msghdr_t needs to bet set to the size of the whole extending type.
44  * For example:
45  *
46  * @code
47  nsapi_pktinfo_t pkt_info;
48  pkt_info.hdr.len = sizeof(nsapi_pktinfo_t);
49  * @endcode
50  *
51  * This value is used in the MsgHeaderIterator to calculate proper addresses of the list elements.
52  *
53  * @par Example
54  *
55  * Code presenting minimal usage example.
56  *
57  * @code
58  struct default_buffer_t {
59  default_buffer_t()
60  {
61  el1.hdr.len = sizeof(nsapi_pktinfo_t);
62  el2.len = sizeof(nsapi_msghdr_t);
63  el3.len = sizeof(nsapi_msghdr_t);
64  el4.hdr.len = sizeof(nsapi_pktinfo_t);
65  }
66  nsapi_pktinfo_t el1;
67  nsapi_msghdr_t el2;
68  nsapi_msghdr_t el3;
69  nsapi_pktinfo_t el4;
70  };
71 
72  default_buffer buff;
73  nsapi_msghdr_t *hdr_p = reinterpret_cast<nsapi_msghdr_t *>(&buff);
74 
75  MsgHeaderIterator it(hdr_p, sizeof(buff));
76 
77  it.has_next() // returns true
78  auto p1 = it.next() // returns pointer to el1
79  auto p2 = it.next() // returns pointer to el2
80  auto p3 = it.next() // returns pointer to el3
81  auto p4 = it.next() // returns pointer to el4
82 
83  it.has_next() // returns false
84  auto p5 = it.next() // returns nullptr
85  * @endcode
86  *
87  * @note More usage examples are implemented in the MsgHeaderIterator unit test
88  * in netsocket/tests/UNITTESTS/NetworkStack/test_MsgHeaderIterator.cpp
89  */
90 
92  /** Create a MsgHeaderIterator over given nsapi_msghdr_t list.
93  *
94  * @param hdr Pointer to the first list element.
95  * @param size Size of the whole list.
96  */
98  start(hdr),
99  current(nullptr),
100  size(size)
101  {}
102 
103  /** Checks if the next address of the iterator is a valid list member.
104  *
105  * @retval True if the next address is a valid member.
106  * @retval False otherwise.
107  */
108  bool has_next()
109  {
110  if (current == nullptr) {
111  if (start != nullptr && start->len <= size && start->len >= sizeof(*start)) {
112  return true;
113  } else {
114  return false;
115  }
116  }
117 
118  if (current->len < sizeof(*current)) {
119  return false;
120  }
121 
122  if (get_next_aligned_addr() >= (reinterpret_cast<uint8_t *>(start) + size)) {
123  return false;
124  }
125 
126  return true;
127  }
128 
129  /** Returns next element of the list.
130  *
131  * @retval nullptr if the list doesn't contain next element.
132  * @retval Pointer to the next element otherwise.
133  */
135  {
136  if (!has_next()) {
137  return nullptr;
138  }
139 
140  if (current == nullptr) {
141  current = start;
142  } else {
143  current = reinterpret_cast<nsapi_msghdr *>(get_next_aligned_addr());
144  }
145 
146  return current;
147  }
148 
149 private:
150  // Get address of the next member aligned to the size of msghdr_t.
151  void *get_next_aligned_addr()
152  {
153  size_t remaining_size = size - (reinterpret_cast<uintptr_t>(current) - reinterpret_cast<uintptr_t>(start));
154  void *next = reinterpret_cast<void *>(reinterpret_cast<uint8_t *>(current) + current->len);
155 
156  next = std::align(
157  alignof(nsapi_msghdr_t),
158  sizeof(nsapi_msghdr_t),
159  next,
160  remaining_size
161  );
162 
163  return next;
164  }
165 
166  nsapi_msghdr_t *start;
167  nsapi_msghdr_t *current;
168  nsapi_size_t size;
169 };
170 
171 
172 #endif
173 
nsapi_msghdr
Definition: nsapi_types.h:414
MsgHeaderIterator(nsapi_msghdr_t *hdr, nsapi_size_t size)
Create a MsgHeaderIterator over given nsapi_msghdr_t list.
Definition: MsgHeader.h:97
bool has_next()
Checks if the next address of the iterator is a valid list member.
Definition: MsgHeader.h:108
nsapi_msghdr_t * next()
Returns next element of the list.
Definition: MsgHeader.h:134
unsigned int nsapi_size_t
Type used to represent the size of data passed through sockets.
Definition: nsapi_types.h:146
Allows iteration through the list of message headers received in the control parameter of the socket_...
Definition: MsgHeader.h:91
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.