gsm0808: add encoder for cause codes and use it

At the moment the all gsm0808 cause codes are encoded directly using the
tlv API directly to put a one byte TLV field. This works ok for most
situations where the cause code consists of a single byte. However,
gsm0808 specifies a two byte cause code model where cause codes may be
extended up to two bytes. Instead of implementing the encoding over and
over and again, let's rather have an encoder function we can call.

- Add an encoder function that can generate single byte and extended
  cause codeds and makes the length decision automatically.

- Use only this function to append cause codes

Change-Id: I71d58fad89502a43532f60717ca022c15c73f8bb
diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c
index c0d5f39..e951ab1 100644
--- a/src/gsm/gsm0808.c
+++ b/src/gsm/gsm0808.c
@@ -141,7 +141,7 @@
 		return NULL;
 
 	msgb_v_put(msg, BSS_MAP_MSG_RESET);
-	msgb_tlv_put(msg, GSM0808_IE_CAUSE, 1, &cause);
+	gsm0808_enc_cause(msg, cause);
 	msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
 
 	return msg;
@@ -190,7 +190,7 @@
 
 	msg->l3h = msgb_tv_put(msg, BSSAP_MSG_BSS_MANAGEMENT, 4);
 	msgb_v_put(msg, BSS_MAP_MSG_CLEAR_CMD);
-	msgb_tlv_put(msg, GSM0808_IE_CAUSE, 1, &cause);
+	gsm0808_enc_cause(msg, cause);
 
 	return msg;
 }
@@ -273,7 +273,7 @@
 
 	msgb_v_put(msg, BSS_MAP_MSG_CIPHER_MODE_REJECT);
 
-	msgb_tlv_put(msg, GSM0808_IE_CAUSE, 1, (const uint8_t *)&cause);
+	gsm0808_enc_cause(msg, cause);
 
 	msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
 
@@ -286,18 +286,22 @@
  *  \returns callee-allocated msgb with BSSMAP Cipher Mode Reject message */
 struct msgb *gsm0808_create_cipher_reject_ext(enum gsm0808_cause_class class, uint8_t ext)
 {
-	uint8_t c[2];
+	uint16_t cause;
 	struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
 					       "bssmap: cipher mode reject");
 	if (!msg)
 		return NULL;
 
-	c[0] = 0x80 | (class << 4); /* set the high bit to indicate extended cause */
-	c[1] = ext;
+	/* Set cause code class in the upper byte */
+	cause = 0x80 | (class << 4);
+	cause = cause << 8;
+
+	/* Set cause code extension in the lower byte */
+	cause |= ext;
 
 	msgb_v_put(msg, BSS_MAP_MSG_CIPHER_MODE_REJECT);
 
-	msgb_tlv_put(msg, GSM0808_IE_CAUSE, 2, c);
+	gsm0808_enc_cause(msg, cause);
 
 	msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
 
@@ -572,7 +576,7 @@
 		return NULL;
 
 	msgb_v_put(msg, BSS_MAP_MSG_ASSIGMENT_FAILURE);
-	msgb_tlv_put(msg, GSM0808_IE_CAUSE, 1, &cause);
+	gsm0808_enc_cause(msg, cause);
 
 	/* RR cause 3.2.2.22 */
 	if (rr_cause)
@@ -614,7 +618,7 @@
 		return NULL;
 
 	msgb_v_put(msg, BSS_MAP_MSG_CLEAR_RQST);
-	msgb_tlv_put(msg, GSM0808_IE_CAUSE, 1, &cause);
+	gsm0808_enc_cause(msg, cause);
 	msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
 
 	return msg;
@@ -751,7 +755,7 @@
 	msgb_v_put(msg, BSS_MAP_MSG_HANDOVER_REQUIRED);
 
 	/* Cause, 3.2.2.5 */
-	msgb_tlv_put(msg, GSM0808_IE_CAUSE, params->cause & 0x80? 2 : 1, (const uint8_t*)&params->cause);
+	gsm0808_enc_cause(msg, params->cause);
 
 	/* Cell Identifier List, 3.2.2.27 */
 	gsm0808_enc_cell_id_list2(msg, &params->cil);
@@ -876,7 +880,7 @@
 	msgb_v_put(msg, BSS_MAP_MSG_HANDOVER_FAILURE);
 
 	/* Cause, 3.2.2.5 */
-	msgb_tlv_put(msg, GSM0808_IE_CAUSE, params->cause & 0x80? 2 : 1, (const uint8_t*)&params->cause);
+	gsm0808_enc_cause(msg, params->cause);
 
 	/* RR Cause, 3.2.2.22 */
 	if (params->rr_cause_present)
@@ -907,7 +911,7 @@
 	msgb_v_put(msg, BSS_MAP_MSG_HANDOVER_PERFORMED);
 
 	/* Cause, 3.2.2.5 */
-	msgb_tlv_put(msg, GSM0808_IE_CAUSE, gsm0808_cause_ext(params->cause) ? 2 : 1, (const uint8_t *)&params->cause);
+	gsm0808_enc_cause(msg, params->cause);
 
 	/* Cell Identifier, 3.2.2.17 */
 	gsm0808_enc_cell_id(msg, &params->cell_id);