OM2000: Add IS Conf Req
diff --git a/openbsc/include/openbsc/abis_om2000.h b/openbsc/include/openbsc/abis_om2000.h
index 5ee3338..f15a50d 100644
--- a/openbsc/include/openbsc/abis_om2000.h
+++ b/openbsc/include/openbsc/abis_om2000.h
@@ -29,6 +29,12 @@
 	uint8_t inst;
 } __attribute__ ((packed));
 
+struct om2k_is_conn_grp {
+	uint16_t icp1;
+	uint16_t icp2;
+	uint8_t cont_idx;
+} __attribute__ ((packed));
+
 extern const struct value_string om2k_mo_class_short_vals[];
 
 int abis_om2k_rcvmsg(struct msgb *msg);
@@ -45,6 +51,8 @@
 int abis_om2k_tx_test_req(struct gsm_bts *bts, const struct abis_om2k_mo *mo);
 int abis_om2k_tx_op_info(struct gsm_bts *bts, const struct abis_om2k_mo *mo,
 			 uint8_t operational);
+int abis_om2k_tx_is_conf_req(struct gsm_bts *bts, struct om2k_is_conn_grp *cg,
+			     unsigned int num_cg);
 
 int abis_om2k_vty_init(void);
 
diff --git a/openbsc/src/abis_om2000.c b/openbsc/src/abis_om2000.c
index f8c876f..e94c715 100644
--- a/openbsc/src/abis_om2000.c
+++ b/openbsc/src/abis_om2000.c
@@ -134,6 +134,9 @@
 
 enum abis_om2k_dei {
 	OM2K_DEI_CAL_TIME			= 0x0d,
+	OM2K_DEI_END_LIST_NR			= 0x13,
+	OM2K_DEI_IS_CONN_LIST			= 0x27,
+	OM2K_DEI_LIST_NR			= 0x28,
 	OM2K_DEI_OP_INFO			= 0x2e,
 	OM2K_DEI_NEGOT_REC1			= 0x90,
 	OM2K_DEI_NEGOT_REC2			= 0x91,
@@ -510,6 +513,7 @@
 }
 
 const struct abis_om2k_mo om2k_mo_cf = { OM2K_MO_CLS_CF, 0, 0xFF, 0 };
+const struct abis_om2k_mo om2k_mo_is = { OM2K_MO_CLS_IS, 0, 0xFF, 0 };
 
 static int abis_om2k_cal_time_resp(struct gsm_bts *bts)
 {
@@ -607,6 +611,25 @@
 	return abis_om2k_sendmsg(bts, msg);
 }
 
+int abis_om2k_tx_is_conf_req(struct gsm_bts *bts, struct om2k_is_conn_grp *cg,
+			     unsigned int num_cg )
+{
+	struct msgb *msg = om2k_msgb_alloc();
+	struct abis_om2k_hdr *o2k;
+
+	o2k = (struct abis_om2k_hdr *) msgb_put(msg, sizeof(*o2k));
+	fill_om2k_hdr(o2k, &om2k_mo_is, OM2K_MSGT_IS_CONF_REQ,
+		      2 + 2 + TLV_GROSS_LEN(num_cg * sizeof(*cg)));
+
+	msgb_tv_put(msg, OM2K_DEI_LIST_NR, 1);
+	msgb_tv_put(msg, OM2K_DEI_END_LIST_NR, 1);
+
+	msgb_tlv_put(msg, OM2K_DEI_IS_CONN_LIST,
+		     num_cg * sizeof(*cg), (uint8_t *)cg);
+
+	return abis_om2k_sendmsg(bts, msg);
+}
+
 static int abis_om2k_tx_negot_req_ack(struct gsm_bts *bts, const struct abis_om2k_mo *mo,
 				      uint8_t *data, unsigned int len)
 {
diff --git a/openbsc/src/abis_om2000_vty.c b/openbsc/src/abis_om2000_vty.c
index bddca52..0bef909 100644
--- a/openbsc/src/abis_om2000_vty.c
+++ b/openbsc/src/abis_om2000_vty.c
@@ -227,6 +227,28 @@
 	return CMD_SUCCESS;
 }
 
+static void om2k_fill_is_conn_grp(struct om2k_is_conn_grp *grp, uint16_t icp1,
+				  uint16_t icp2, uint8_t cont_idx)
+{
+	grp->icp1 = htons(icp1);
+	grp->icp2 = htons(icp2);
+	grp->cont_idx = cont_idx;
+}
+
+DEFUN(om2k_is_conf_req, om2k_is_conf_req_cmd,
+	"is-conf-req",
+	"IS Configuration Request\n")
+{
+	struct oml_node_state *oms = vty->index;
+	struct om2k_is_conn_grp grps[3];
+
+	om2k_fill_is_conn_grp(&grps[0], 512,  4, 4);
+	om2k_fill_is_conn_grp(&grps[1], 516,  8, 4);
+	om2k_fill_is_conn_grp(&grps[2], 520, 12, 4);
+
+	abis_om2k_tx_is_conf_req(oms->bts, grps, ARRAY_SIZE(grps));
+	return CMD_SUCCESS;
+}
 
 int abis_om2k_vty_init(void)
 {
@@ -245,6 +267,7 @@
 	install_element(OM2K_NODE, &om2k_disable_cmd);
 	install_element(OM2K_NODE, &om2k_op_info_cmd);
 	install_element(OM2K_NODE, &om2k_test_cmd);
+	install_element(OM2K_NODE, &om2k_is_conf_req_cmd);
 
 	return 0;
 }