[PATCH] libosmocore[master]: Add SW Description (de)marshalling

2017-04-11 Thread Max
Hello Neels Hofmeyr, Jenkins Builder,

I'd like you to reexamine a change.  Please visit

https://gerrit.osmocom.org/2165

to look at the new patch set (#14).

Add SW Description (de)marshalling

* data structure representing 3GPP TS 52.021 §9.4.62 SW Description
* function to serialize it into msgb
* function to deserialize it from buffer
* functions to extract/estimate buffer size for SW Description
* test harness (partially taken from OpenBSC)

There are several similar functions to deal with SW Description in
OpenBSC, there's also need to use similar functionality in
OsmoBTS. Hence it's better to put the code into common library with
proper tests and documentation.

Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd
Related: OS#1614
---
M .gitignore
M include/osmocom/gsm/protocol/gsm_12_21.h
M src/gsm/abis_nm.c
M src/gsm/libosmogsm.map
M tests/Makefile.am
A tests/abis/abis_test.c
A tests/abis/abis_test.ok
M tests/testsuite.at
8 files changed, 437 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/65/2165/14

diff --git a/.gitignore b/.gitignore
index ecbcedd..4c6a78f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -60,6 +60,7 @@
 tests/testsuite
 tests/testsuite.dir/
 tests/testsuite.log
+tests/abis/abis_test
 tests/ctrl/ctrl_test
 tests/utils/utils_test
 tests/stats/stats_test
diff --git a/include/osmocom/gsm/protocol/gsm_12_21.h 
b/include/osmocom/gsm/protocol/gsm_12_21.h
index c88f0b1..b35da44 100644
--- a/include/osmocom/gsm/protocol/gsm_12_21.h
+++ b/include/osmocom/gsm/protocol/gsm_12_21.h
@@ -29,6 +29,7 @@
 /*! \file gsm_12_21.h */
 
 #include 
+#include 
 #include 
 
 /*! \brief generic header in front of every OML message according to TS 08.59 
*/
@@ -791,6 +792,21 @@
IPAC_BINF_CELL_ALLOC= (1 << 2),
 };
 
+/*! \brief 3GPP TS 52.021 §9.4.62 SW Description */
+struct abis_nm_sw_desc {
+   uint8_t file_id[UINT8_MAX];
+   uint8_t file_id_len;
+
+   uint8_t file_version[UINT8_MAX];
+   uint8_t file_version_len;
+};
+
+uint16_t abis_nm_sw_desc_len(const struct abis_nm_sw_desc *sw, bool 
put_sw_descr);
+uint16_t abis_nm_put_sw_desc(struct msgb *msg, const struct abis_nm_sw_desc 
*sw, bool put_sw_descr);
+uint16_t abis_nm_put_sw_file(struct msgb *msg, const char *id, const char 
*ver, bool put_sw_desc);
+uint32_t abis_nm_get_sw_desc_len(const uint8_t * buf, size_t len);
+int abis_nm_get_sw_conf(const uint8_t * buf, size_t buf_len, struct 
abis_nm_sw_desc *sw, uint16_t sw_len);
+
 struct msgb *abis_nm_fail_evt_rep(enum abis_nm_event_type t,
  enum abis_nm_severity s,
  enum abis_nm_pcause_type ct,
diff --git a/src/gsm/abis_nm.c b/src/gsm/abis_nm.c
index 934d7ce..7553f84 100644
--- a/src/gsm/abis_nm.c
+++ b/src/gsm/abis_nm.c
@@ -751,6 +751,161 @@
return nmsg;
 }
 
+/*! \brief Compute length of given 3GPP TS 52.021 §9.4.62 SW Description.
+ *  \param[in] sw SW Description struct
+ *  \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not
+ *  \returns length of buffer space necessary to store sw
+ */
+uint16_t abis_nm_sw_desc_len(const struct abis_nm_sw_desc *sw, bool 
put_sw_desc)
+{
+   /* +3: type is 1-byte, length is 2-byte */
+   return (put_sw_desc ? 1 : 0) + (sw->file_id_len + 3) + 
(sw->file_version_len + 3);
+}
+
+/*! \brief Put given 3GPP TS 52.021 §9.4.62 SW Description into msgb.
+ *  \param[out] msg message buffer
+ *  \param[in] sw SW Description struct
+ *  \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not
+ *  \returns length of buffer space necessary to store sw
+ */
+uint16_t abis_nm_put_sw_desc(struct msgb *msg, const struct abis_nm_sw_desc 
*sw, bool put_sw_desc)
+{
+   if (put_sw_desc)
+   msgb_v_put(msg, NM_ATT_SW_DESCR);
+
+   msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id);
+   msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len, 
sw->file_version);
+
+   return abis_nm_sw_desc_len(sw, put_sw_desc);
+}
+
+/*! \brief Put given file ID/Version pair as 3GPP TS 52.021 §9.4.62 SW 
Description into msgb.
+ *  \param[out] msg message buffer
+ *  \param[in] id File ID part of SW Description
+ *  \param[in] id File Version part of SW Description
+ *  \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not
+ *  \returns length of buffer space necessary to store sw
+ */
+uint16_t abis_nm_put_sw_file(struct msgb *msg, const char *id, const char 
*ver, bool put_sw_desc)
+{
+   struct abis_nm_sw_desc sw = {
+   .file_id_len = strlen(id),
+   .file_version_len = strlen(ver),
+   };
+
+   memcpy(sw.file_id, id, sw.file_id_len);
+   memcpy(sw.file_version, ver, sw.file_version_len);
+
+   return abis_nm_put_sw_desc(msg, , put_sw_desc);
+}
+
+/*! \brief Get length of first 3GPP TS 52.021 §9.4.62 SW Description from 
buffer.
+ *  \param[in] buf buffer, may contain several SW 

[PATCH] libosmocore[master]: Add SW Description (de)marshalling

2017-04-04 Thread Max
Hello Neels Hofmeyr, Jenkins Builder,

I'd like you to reexamine a change.  Please visit

https://gerrit.osmocom.org/2165

to look at the new patch set (#12).

Add SW Description (de)marshalling

* data structure representing 3GPP TS 52.021 §9.4.62 SW Description
* function to serialize it into msgb
* function to deserialize it from buffer
* functions to extract/estimate buffer size for SW Description
* test harness (partially taken from OpenBSC)

There are several similar functions to deal with SW Description in
OpenBSC, there's also need to use similar functionality in
OsmoBTS. Hence it's better to put the code into common library with
proper tests and documentation.

Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd
Related: OS#1614
---
M .gitignore
M include/osmocom/gsm/protocol/gsm_12_21.h
M src/gsm/abis_nm.c
M src/gsm/libosmogsm.map
M tests/Makefile.am
A tests/abis/abis_test.c
A tests/abis/abis_test.ok
M tests/testsuite.at
8 files changed, 437 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/65/2165/12

diff --git a/.gitignore b/.gitignore
index ecbcedd..4c6a78f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -60,6 +60,7 @@
 tests/testsuite
 tests/testsuite.dir/
 tests/testsuite.log
+tests/abis/abis_test
 tests/ctrl/ctrl_test
 tests/utils/utils_test
 tests/stats/stats_test
diff --git a/include/osmocom/gsm/protocol/gsm_12_21.h 
b/include/osmocom/gsm/protocol/gsm_12_21.h
index c88f0b1..09d8432 100644
--- a/include/osmocom/gsm/protocol/gsm_12_21.h
+++ b/include/osmocom/gsm/protocol/gsm_12_21.h
@@ -29,6 +29,7 @@
 /*! \file gsm_12_21.h */
 
 #include 
+#include 
 #include 
 
 /*! \brief generic header in front of every OML message according to TS 08.59 
*/
@@ -791,6 +792,22 @@
IPAC_BINF_CELL_ALLOC= (1 << 2),
 };
 
+/*! \brief 3GPP TS 52.021 §9.4.62 SW Description */
+struct abis_nm_sw_descr {
+   uint8_t file_id[UINT8_MAX];
+   uint8_t file_id_len;
+
+   uint8_t file_version[UINT8_MAX];
+   uint8_t file_version_len;
+};
+
+uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw,
+ bool put_sw_descr);
+uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr 
*sw,
+ bool put_sw_descr);
+uint32_t abis_nm_get_sw_descr_len(const uint8_t * buf, size_t len);
+int abis_nm_get_sw_conf(const uint8_t * buf, size_t buf_len,
+   struct abis_nm_sw_descr *sw, uint16_t sw_len);
 struct msgb *abis_nm_fail_evt_rep(enum abis_nm_event_type t,
  enum abis_nm_severity s,
  enum abis_nm_pcause_type ct,
diff --git a/src/gsm/abis_nm.c b/src/gsm/abis_nm.c
index 934d7ce..4acd322 100644
--- a/src/gsm/abis_nm.c
+++ b/src/gsm/abis_nm.c
@@ -751,6 +751,148 @@
return nmsg;
 }
 
+/*! \brief Compute length of given 3GPP TS 52.021 §9.4.62 SW Description.
+ *  \param[in] sw SW Description struct
+ *  \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not
+ *  \returns length of buffer space necessary to store sw
+ */
+uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw,
+ bool put_sw_descr)
+{
+   /* +3: type is 1-byte, length is 2-byte */
+   return (put_sw_descr ? 1 : 0) + (sw->file_id_len + 3) +
+  (sw->file_version_len + 3);
+}
+
+/*! \brief Put given 3GPP TS 52.021 §9.4.62 SW Description into msgb.
+ *  \param[out] msg message buffer
+ *  \param[in] sw SW Description struct
+ *  \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not
+ *  \param[in] simulate boolean, whether to actually modify msg or not
+ *  \returns length of buffer space necessary to store sw
+ */
+uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr 
*sw,
+ bool put_sw_descr)
+{
+   if (put_sw_descr)
+   msgb_v_put(msg, NM_ATT_SW_DESCR);
+   msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id);
+   msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len,
+  sw->file_version);
+
+   return abis_nm_sw_descr_len(sw, put_sw_descr);
+}
+
+/*! \brief Get length of first 3GPP TS 52.021 §9.4.62 SW Description from 
buffer.
+ *  \param[in] buf buffer, may contain several SW Descriptions
+ *  \param[in] len buffer length
+ *  \returns length if parsing succeeded, 0 otherwise
+ */
+uint32_t abis_nm_get_sw_descr_len(const uint8_t *buf, size_t len)
+{
+   uint16_t sw = 2; /* 1-byte SW tag + 1-byte FILE_* tag */
+
+   if (buf[0] != NM_ATT_SW_DESCR)
+   sw = 1; /* 1-byte FILE_* tag */
+
+   if (buf[sw - 1] != NM_ATT_FILE_ID && buf[sw - 1] != NM_ATT_FILE_VERSION)
+   return 0;
+
+   /* + length of 1st FILE_* element + 1-byte tag + 2-byte length field of
+  1st FILE_* element */
+   sw += (osmo_load16be(buf + sw) + 3);
+
+   /* + length of 2nd FILE_* 

[PATCH] libosmocore[master]: Add SW Description (de)marshalling

2017-04-04 Thread Max
Hello Neels Hofmeyr, Jenkins Builder,

I'd like you to reexamine a change.  Please visit

https://gerrit.osmocom.org/2165

to look at the new patch set (#10).

Add SW Description (de)marshalling

* data structure representing 3GPP TS 52.021 §9.4.62 SW Description
* function to serialize it into msgb
* function to deserialize it from buffer
* functions to extract/estimate buffer size for SW Description
* test harness

There are several similar functions to deal with SW Description in
OpenBSC, there's also need to use similar functionality in
OsmoBTS. Hence it's better to put the code into common library with
proper tests and documentation.

Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd
Related: OS#1614
---
M include/osmocom/gsm/protocol/gsm_12_21.h
M src/gsm/abis_nm.c
M src/gsm/libosmogsm.map
M tests/Makefile.am
M tests/lapd/lapd_test.c
M tests/lapd/lapd_test.ok
6 files changed, 285 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/65/2165/10

diff --git a/include/osmocom/gsm/protocol/gsm_12_21.h 
b/include/osmocom/gsm/protocol/gsm_12_21.h
index c88f0b1..427f472 100644
--- a/include/osmocom/gsm/protocol/gsm_12_21.h
+++ b/include/osmocom/gsm/protocol/gsm_12_21.h
@@ -29,6 +29,7 @@
 /*! \file gsm_12_21.h */
 
 #include 
+#include 
 #include 
 
 /*! \brief generic header in front of every OML message according to TS 08.59 
*/
@@ -791,6 +792,23 @@
IPAC_BINF_CELL_ALLOC= (1 << 2),
 };
 
+/*! \brief 3GPP TS 52.021 §9.4.62 SW Description */
+struct abis_nm_sw_descr {
+   uint8_t file_id[UINT8_MAX];
+   uint8_t file_id_len;
+
+   uint8_t file_version[UINT8_MAX];
+   uint8_t file_version_len;
+};
+
+uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw,
+ bool put_sw_descr);
+uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr 
*sw,
+ bool put_sw_descr);
+uint32_t abis_nm_get_sw_descr_len(const uint8_t * buf, size_t len);
+int abis_nm_get_sw_conf(struct abis_nm_sw_descr *sw, uint16_t sw_len,
+   const uint8_t * buf, size_t buf_len);
+
 struct msgb *abis_nm_fail_evt_rep(enum abis_nm_event_type t,
  enum abis_nm_severity s,
  enum abis_nm_pcause_type ct,
diff --git a/src/gsm/abis_nm.c b/src/gsm/abis_nm.c
index 934d7ce..e87188a 100644
--- a/src/gsm/abis_nm.c
+++ b/src/gsm/abis_nm.c
@@ -751,6 +751,148 @@
return nmsg;
 }
 
+/*! \brief Compute length of given 3GPP TS 52.021 §9.4.62 SW Description.
+ *  \param[in] sw SW Description struct
+ *  \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not
+ *  \returns length of buffer space necessary to store sw
+ */
+uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw,
+ bool put_sw_descr)
+{
+   /* +3: type is 1-byte, length is 2-byte */
+   return (put_sw_descr ? 1 : 0) + (sw->file_id_len + 3) +
+  (sw->file_version_len + 3);
+}
+
+/*! \brief Put given 3GPP TS 52.021 §9.4.62 SW Description into msgb.
+ *  \param[out] msg message buffer
+ *  \param[in] sw SW Description struct
+ *  \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not
+ *  \param[in] simulate boolean, whether to actually modify msg or not
+ *  \returns length of buffer space necessary to store sw
+ */
+uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr 
*sw,
+ bool put_sw_descr)
+{
+   if (put_sw_descr)
+   msgb_v_put(msg, NM_ATT_SW_DESCR);
+   msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id);
+   msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len,
+  sw->file_version);
+
+   return abis_nm_sw_descr_len(sw, put_sw_descr);
+}
+
+/*! \brief Get length of first 3GPP TS 52.021 §9.4.62 SW Description from 
buffer.
+ *  \param[in] buf buffer, may contain several SW Descriptions
+ *  \param[in] len buffer length
+ *  \returns length if parsing succeeded, 0 otherwise
+ */
+uint32_t abis_nm_get_sw_descr_len(const uint8_t *buf, size_t len)
+{
+   uint16_t sw = 2; /* 1-byte SW tag + 1-byte FILE_* tag */
+
+   if (buf[0] != NM_ATT_SW_DESCR)
+   sw = 1; /* 1-byte FILE_* tag */
+
+   if (buf[sw - 1] != NM_ATT_FILE_ID && buf[sw - 1] != NM_ATT_FILE_VERSION)
+   return 0;
+
+   /* + length of 1st FILE_* element + 1-byte tag + 2-byte length field of
+  1st FILE_* element */
+   sw += (osmo_load16be(buf + sw) + 3);
+
+   /* + length of 2nd FILE_* element */
+   sw += osmo_load16be(buf + sw);
+
+   return sw + 2; /* +  2-byte length field of 2nd FILE_* element */
+}
+
+/*! \brief Parse single 3GPP TS 52.021 §9.4.62 SW Description from buffer.
+ *  \param[out] sw SW Description struct
+ *  \param[in] buf buffer
+ *  \param[in] len buffer length
+ *  \returns 0 if 

[PATCH] libosmocore[master]: Add SW Description (de)marshalling

2017-04-04 Thread Max
Hello Neels Hofmeyr, Jenkins Builder,

I'd like you to reexamine a change.  Please visit

https://gerrit.osmocom.org/2165

to look at the new patch set (#9).

Add SW Description (de)marshalling

* data structure representing 3GPP TS 52.021 §9.4.62 SW Description
* function to serialize it into msgb
* function to deserialize it from buffer
* function to estimate buffer size
* test harness

There are several similar functions to deal with SW Description in
OpenBSC, there's also need to use similar functionality in
OsmoBTS. Hence it's better to put the code into common library with
proper tests and documentation.

Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd
Related: OS#1614
---
M include/osmocom/gsm/protocol/gsm_12_21.h
M src/gsm/abis_nm.c
M src/gsm/libosmogsm.map
M tests/Makefile.am
M tests/lapd/lapd_test.c
M tests/lapd/lapd_test.ok
6 files changed, 258 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/65/2165/9

diff --git a/include/osmocom/gsm/protocol/gsm_12_21.h 
b/include/osmocom/gsm/protocol/gsm_12_21.h
index c88f0b1..aa74382 100644
--- a/include/osmocom/gsm/protocol/gsm_12_21.h
+++ b/include/osmocom/gsm/protocol/gsm_12_21.h
@@ -29,6 +29,7 @@
 /*! \file gsm_12_21.h */
 
 #include 
+#include 
 #include 
 
 /*! \brief generic header in front of every OML message according to TS 08.59 
*/
@@ -791,6 +792,23 @@
IPAC_BINF_CELL_ALLOC= (1 << 2),
 };
 
+/*! \brief 3GPP TS 52.021 §9.4.62 SW Description */
+struct abis_nm_sw_descr {
+   uint8_t file_id[UINT8_MAX];
+   uint8_t file_id_len;
+
+   uint8_t file_version[UINT8_MAX];
+   uint8_t file_version_len;
+};
+
+uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw,
+ bool put_sw_descr);
+uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr 
*sw,
+ bool put_sw_descr);
+uint32_t abis_nm_get_sw_descr_len(const uint8_t * buf, size_t len);
+int abis_nm_get_sw_descr_one(struct abis_nm_sw_descr *sw, const uint8_t * buf,
+size_t len);
+
 struct msgb *abis_nm_fail_evt_rep(enum abis_nm_event_type t,
  enum abis_nm_severity s,
  enum abis_nm_pcause_type ct,
diff --git a/src/gsm/abis_nm.c b/src/gsm/abis_nm.c
index 934d7ce..98708a4 100644
--- a/src/gsm/abis_nm.c
+++ b/src/gsm/abis_nm.c
@@ -751,6 +751,121 @@
return nmsg;
 }
 
+/*! \brief Compute length of given 3GPP TS 52.021 §9.4.62 SW Description.
+ *  \param[in] sw SW Description struct
+ *  \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not
+ *  \returns length of buffer space necessary to store sw
+ */
+uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw,
+ bool put_sw_descr)
+{
+   /* +3: type is 1-byte, length is 2-byte */
+   return (put_sw_descr ? 1 : 0) + (sw->file_id_len + 3) +
+  (sw->file_version_len + 3);
+}
+
+/*! \brief Put given 3GPP TS 52.021 §9.4.62 SW Description into msgb.
+ *  \param[out] msg message buffer
+ *  \param[in] sw SW Description struct
+ *  \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not
+ *  \param[in] simulate boolean, whether to actually modify msg or not
+ *  \returns length of buffer space necessary to store sw
+ */
+uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr 
*sw,
+ bool put_sw_descr)
+{
+   if (put_sw_descr)
+   msgb_v_put(msg, NM_ATT_SW_DESCR);
+   msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id);
+   msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len,
+  sw->file_version);
+
+   return abis_nm_sw_descr_len(sw, put_sw_descr);
+}
+
+/*! \brief Get length of first 3GPP TS 52.021 §9.4.62 SW Description from 
buffer.
+ *  \param[in] buf buffer, may contain several SW Descriptions
+ *  \param[in] len buffer length
+ *  \returns length if parsing succeeded, 0 otherwise
+ */
+uint32_t abis_nm_get_sw_descr_len(const uint8_t *buf, size_t len)
+{
+   uint16_t sw = 2; /* 1-byte SW tag + 1-byte FILE_* tag */
+
+   if (buf[0] != NM_ATT_SW_DESCR)
+   sw = 1; /* 1-byte FILE_* tag */
+
+   if (buf[sw - 1] != NM_ATT_FILE_ID && buf[sw - 1] != NM_ATT_FILE_VERSION)
+   return 0;
+
+   /* + length of 1st FILE_* element + 1-byte tag + 2-byte length field of
+  1st FILE_* element */
+   sw += (osmo_load16be(buf + sw) + 3);
+
+   /* + length of 2nd FILE_* element */
+   sw += osmo_load16be(buf + sw);
+
+   return sw + 2; /* +  2-byte length field of 2nd FILE_* element */
+}
+
+/*! \brief Parse single 3GPP TS 52.021 §9.4.62 SW Description from buffer.
+ *  \param[out] sw SW Description struct
+ *  \param[in] buf buffer
+ *  \param[in] len buffer length
+ *  \returns 0 if parsing succeeded, negative error code 

[PATCH] libosmocore[master]: Add SW Description (de)marshalling

2017-04-03 Thread Max
Hello Neels Hofmeyr, Jenkins Builder,

I'd like you to reexamine a change.  Please visit

https://gerrit.osmocom.org/2165

to look at the new patch set (#5).

Add SW Description (de)marshalling

* data structure representing 3GPP TS 52.021 §9.4.62 SW Description
* function to serialize it into msgb
* function to deserialize it from buffer
* function to estimate buffer size
* test harness

There are several similar functions to deal with SW Description in
OpenBSC, there's also need to use similar functionality in
OsmoBTS. Hence it's better to put the code into common library with
proper tests and documentation.

Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd
Related: OS#1614
---
M include/osmocom/gsm/protocol/gsm_12_21.h
M src/gsm/abis_nm.c
M src/gsm/libosmogsm.map
M tests/Makefile.am
M tests/lapd/lapd_test.c
M tests/lapd/lapd_test.ok
6 files changed, 160 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/65/2165/5

diff --git a/include/osmocom/gsm/protocol/gsm_12_21.h 
b/include/osmocom/gsm/protocol/gsm_12_21.h
index c88f0b1..3e6bb2b 100644
--- a/include/osmocom/gsm/protocol/gsm_12_21.h
+++ b/include/osmocom/gsm/protocol/gsm_12_21.h
@@ -29,6 +29,7 @@
 /*! \file gsm_12_21.h */
 
 #include 
+#include 
 #include 
 
 /*! \brief generic header in front of every OML message according to TS 08.59 
*/
@@ -791,6 +792,22 @@
IPAC_BINF_CELL_ALLOC= (1 << 2),
 };
 
+/*! \brief 3GPP TS 52.021 §9.4.62 SW Description */
+struct abis_nm_sw_descr {
+   uint8_t file_id[UINT8_MAX];
+   uint8_t file_id_len;
+
+   uint8_t file_version[UINT8_MAX];
+   uint8_t file_version_len;
+};
+
+uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw,
+ bool put_sw_descr);
+uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr 
*sw,
+ bool put_sw_descr);
+bool abis_nm_get_sw_descr(struct abis_nm_sw_descr *sw, const uint8_t * buf,
+ size_t len);
+
 struct msgb *abis_nm_fail_evt_rep(enum abis_nm_event_type t,
  enum abis_nm_severity s,
  enum abis_nm_pcause_type ct,
diff --git a/src/gsm/abis_nm.c b/src/gsm/abis_nm.c
index 934d7ce..6dbc45a 100644
--- a/src/gsm/abis_nm.c
+++ b/src/gsm/abis_nm.c
@@ -751,6 +751,81 @@
return nmsg;
 }
 
+/*! \brief Compute length of given 3GPP TS 52.021 §9.4.62 SW Description.
+ *  \param[in] sw SW Description struct
+ *  \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not
+ *  \returns length of buffer space necessary to store sw
+ */
+uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw,
+ bool put_sw_descr)
+{
+   /* +3: type is 1-byte, length is 2-byte */
+   return (put_sw_descr ? 1 : 0) + (sw->file_id_len + 3) +
+  (sw->file_version_len + 3);
+}
+
+/*! \brief Put given 3GPP TS 52.021 §9.4.62 SW Description into msgb.
+ *  \param[out] msg message buffer
+ *  \param[in] sw SW Description struct
+ *  \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not
+ *  \param[in] simulate boolean, whether to actually modify msg or not
+ *  \returns length of buffer space necessary to store sw
+ */
+uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr 
*sw,
+ bool put_sw_descr)
+{
+   if (put_sw_descr)
+   msgb_v_put(msg, NM_ATT_SW_DESCR);
+   msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id);
+   msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len,
+  sw->file_version);
+
+   return abis_nm_sw_descr_len(sw, put_sw_descr);
+}
+
+/*! \brief Parse 3GPP TS 52.021 §9.4.62 SW Description from buffer.
+ *  \param[out] sw SW Description struct
+ *  \param[in] buf buffer
+ *  \param[in] len buffer length
+ *  \returns true if parsing succeeded, else otherwise
+ */
+bool abis_nm_get_sw_descr(struct abis_nm_sw_descr *sw, const uint8_t * buf,
+ size_t len)
+{
+   static struct tlv_parsed tp;
+   const struct tlv_definition sw_tlvdef = {
+   .def = {
+   [NM_ATT_SW_DESCR] = { TLV_TYPE_TV },
+   [NM_ATT_FILE_ID] =  { TLV_TYPE_TL16V },
+   [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V },
+   },
+   };
+
+   /* Note: the return value is ignored here because SW Description tag
+  itself is considered optional. */
+   tlv_parse(, _tlvdef, buf, len, 0, 0);
+
+   /* Parsing SW Description is tricky for current implementation of TLV
+  parser which fails to properly handle TV when V has following
+  structure: | TL16V | TL16V |. Hence, the need for 2nd call: */
+   if (tlv_parse(, _tlvdef, buf + TLVP_LEN(, NM_ATT_SW_DESCR),
+ len - TLVP_LEN(, 

[PATCH] libosmocore[master]: Add SW Description (de)marshalling

2017-04-03 Thread Max
Hello Neels Hofmeyr, Jenkins Builder,

I'd like you to reexamine a change.  Please visit

https://gerrit.osmocom.org/2165

to look at the new patch set (#4).

Add SW Description (de)marshalling

* data structure representing 3GPP TS 52.021 §9.4.62 SW Description
* function to serialize it into msgb
* function to deserialize it from buffer
* function to estimate buffer size
* test harness

There are several similar functions to deal with SW Description in
OpenBSC, there's also need to use similar functionality in
OsmoBTS. Hence it's better to put the code into common library with
proper tests and documentation.

Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd
Related: OS#1614
---
M include/osmocom/gsm/protocol/gsm_12_21.h
M src/gsm/abis_nm.c
M src/gsm/libosmogsm.map
M tests/Makefile.am
M tests/msgb/msgb_test.c
M tests/msgb/msgb_test.ok
6 files changed, 157 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/65/2165/4

diff --git a/include/osmocom/gsm/protocol/gsm_12_21.h 
b/include/osmocom/gsm/protocol/gsm_12_21.h
index c88f0b1..3e6bb2b 100644
--- a/include/osmocom/gsm/protocol/gsm_12_21.h
+++ b/include/osmocom/gsm/protocol/gsm_12_21.h
@@ -29,6 +29,7 @@
 /*! \file gsm_12_21.h */
 
 #include 
+#include 
 #include 
 
 /*! \brief generic header in front of every OML message according to TS 08.59 
*/
@@ -791,6 +792,22 @@
IPAC_BINF_CELL_ALLOC= (1 << 2),
 };
 
+/*! \brief 3GPP TS 52.021 §9.4.62 SW Description */
+struct abis_nm_sw_descr {
+   uint8_t file_id[UINT8_MAX];
+   uint8_t file_id_len;
+
+   uint8_t file_version[UINT8_MAX];
+   uint8_t file_version_len;
+};
+
+uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw,
+ bool put_sw_descr);
+uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr 
*sw,
+ bool put_sw_descr);
+bool abis_nm_get_sw_descr(struct abis_nm_sw_descr *sw, const uint8_t * buf,
+ size_t len);
+
 struct msgb *abis_nm_fail_evt_rep(enum abis_nm_event_type t,
  enum abis_nm_severity s,
  enum abis_nm_pcause_type ct,
diff --git a/src/gsm/abis_nm.c b/src/gsm/abis_nm.c
index 934d7ce..6dbc45a 100644
--- a/src/gsm/abis_nm.c
+++ b/src/gsm/abis_nm.c
@@ -751,6 +751,81 @@
return nmsg;
 }
 
+/*! \brief Compute length of given 3GPP TS 52.021 §9.4.62 SW Description.
+ *  \param[in] sw SW Description struct
+ *  \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not
+ *  \returns length of buffer space necessary to store sw
+ */
+uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw,
+ bool put_sw_descr)
+{
+   /* +3: type is 1-byte, length is 2-byte */
+   return (put_sw_descr ? 1 : 0) + (sw->file_id_len + 3) +
+  (sw->file_version_len + 3);
+}
+
+/*! \brief Put given 3GPP TS 52.021 §9.4.62 SW Description into msgb.
+ *  \param[out] msg message buffer
+ *  \param[in] sw SW Description struct
+ *  \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not
+ *  \param[in] simulate boolean, whether to actually modify msg or not
+ *  \returns length of buffer space necessary to store sw
+ */
+uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr 
*sw,
+ bool put_sw_descr)
+{
+   if (put_sw_descr)
+   msgb_v_put(msg, NM_ATT_SW_DESCR);
+   msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id);
+   msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len,
+  sw->file_version);
+
+   return abis_nm_sw_descr_len(sw, put_sw_descr);
+}
+
+/*! \brief Parse 3GPP TS 52.021 §9.4.62 SW Description from buffer.
+ *  \param[out] sw SW Description struct
+ *  \param[in] buf buffer
+ *  \param[in] len buffer length
+ *  \returns true if parsing succeeded, else otherwise
+ */
+bool abis_nm_get_sw_descr(struct abis_nm_sw_descr *sw, const uint8_t * buf,
+ size_t len)
+{
+   static struct tlv_parsed tp;
+   const struct tlv_definition sw_tlvdef = {
+   .def = {
+   [NM_ATT_SW_DESCR] = { TLV_TYPE_TV },
+   [NM_ATT_FILE_ID] =  { TLV_TYPE_TL16V },
+   [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V },
+   },
+   };
+
+   /* Note: the return value is ignored here because SW Description tag
+  itself is considered optional. */
+   tlv_parse(, _tlvdef, buf, len, 0, 0);
+
+   /* Parsing SW Description is tricky for current implementation of TLV
+  parser which fails to properly handle TV when V has following
+  structure: | TL16V | TL16V |. Hence, the need for 2nd call: */
+   if (tlv_parse(, _tlvdef, buf + TLVP_LEN(, NM_ATT_SW_DESCR),
+ len - TLVP_LEN(,