fix parse_cell_id_lac_and_ci_list()

The implementation was entirely broken, reading data from wrong offsets
and always writing to the first element of the decoded list.

Also, add a new test for this function which found the problems.

Change-Id: If0fafbc7171da2a3044bfa9a167208a1afa1c07b
Related: OS#2847
Depends: Ife4e485e2b86c6f3321c9700611700115ad247b2
diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c
index 0165e8a..b58a4b8 100644
--- a/src/gsm/gsm0808_utils.c
+++ b/src/gsm/gsm0808_utils.c
@@ -719,7 +719,7 @@
 {
 	uint16_t *lacp_be, *ci_be;
 	struct osmo_lac_and_ci_id *id;
-	int i = 0;
+	int i = 0, j = 0;
 	const size_t elemlen = sizeof(*lacp_be) + sizeof(*ci_be);
 
 	*consumed = 0;
@@ -727,18 +727,19 @@
 	if (remain < elemlen)
 		return -EINVAL;
 
-	lacp_be = (uint16_t *)(&data[0]);
-	ci_be = (uint16_t *)(&data[2]);
+	lacp_be = (uint16_t *)(&data[j]);
+	ci_be = (uint16_t *)(&data[j + elemlen/2]);
 	while (remain >= elemlen) {
 		if (i >= GSM0808_CELL_ID_LIST2_MAXLEN)
 			return -ENOSPC;
-		id = &cil->id_list[i].lac_and_ci;
+		id = &cil->id_list[i++].lac_and_ci;
 		id->lac = osmo_load16be(lacp_be);
 		id->ci = osmo_load16be(ci_be);
 		*consumed += elemlen;
 		remain -= elemlen;
-		lacp_be++;
-		ci_be++;
+		j += elemlen;
+		lacp_be = (uint16_t *)(&data[j]);
+		ci_be = (uint16_t *)(&data[j + elemlen/2]);
 	}
 
 	return i;