From 96b5b249ddd12828726ab14310011f39727253ef Mon Sep 17 00:00:00 2001
From: Maxim Menshikov <maxim.menshikov@iopsys.eu>
Date: Tue, 6 Feb 2024 12:35:39 +0000
Subject: [PATCH] Use UBUS method of sending fragmentation scheme

---
 src/cntlr_map.c | 84 ++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 65 insertions(+), 19 deletions(-)

diff --git a/src/cntlr_map.c b/src/cntlr_map.c
index 5b7bfb71..15ebc7cf 100644
--- a/src/cntlr_map.c
+++ b/src/cntlr_map.c
@@ -66,6 +66,8 @@
 #include "wifi_opclass.h"
 #include "cntlr_map.h"
 
+/* Length of data in CMDU after which we consider that CMDU might might be fragmentized */
+#define FRAG_DATA_SIZE         (1400)
 
 /* Max size is 256 as per the Multi-ap r2 spec */
 #define TIMESTAMP_MAX_LEN 256
@@ -829,6 +831,47 @@ out:
 	return -1;
 }
 
+int send_frag_scheme_ubus(struct controller *c, uint8_t *origin, int frag_scheme)
+{
+	struct blob_buf b = { 0 };
+	char dst_addr[18] = { 0 };
+	uint16_t msgid = 0;
+	int ret = 0;
+	uint32_t id;
+
+	trace("|%s:%d| Entry\n", __func__, __LINE__);
+
+	memset(&b, 0, sizeof(struct blob_buf));
+	blob_buf_init(&b, 0);
+
+	hwaddr_ntoa(origin, dst_addr);
+	blobmsg_add_string(&b, "dst", dst_addr);
+	blobmsg_add_u32(&b, "mode", (uint32_t)frag_scheme);
+
+	if (ubus_lookup_id(c->ubus_ctx, "ieee1905", &id)) {
+		trace("[%s:%d] not present ieee1905", __func__, __LINE__);
+		goto out;
+	}
+
+	ret = ubus_invoke(c->ubus_ctx, id, "frag_scheme",
+	                  b.head, NULL,
+	                  &msgid,
+	                  1000);
+	if (ret) {
+		trace("[%s:%d] ubus call failed for |ieee1905 send|",
+		      __func__, __LINE__);
+		goto out;
+	}
+
+	trace("|%s:%d| msgid = %d\n", __func__, __LINE__, msgid);
+	blob_buf_free(&b);
+	return msgid;
+
+out:
+	blob_buf_free(&b);
+	return -1;
+}
+
 uint16_t send_cmdu(struct controller *a, struct cmdu_buff *cmdu)
 {
 	uint16_t resp_type;
@@ -836,8 +879,6 @@ uint16_t send_cmdu(struct controller *a, struct cmdu_buff *cmdu)
 	void *cookie = NULL;
 	const int resend_num = a->cfg.resend_num;
 	uint16_t msgid, old_mid;
-	struct node *n = NULL;
-	enum cmdu_frag_scheme frag_scheme = CMDU_FRAG_SCHEME_UNKNOWN;
 
 	if (hwaddr_is_ucast(cmdu->origin)) {
 		resp_type = cntlr_cmdu_expect_response(a, cmdu_get_type(cmdu));
@@ -845,25 +886,30 @@ uint16_t send_cmdu(struct controller *a, struct cmdu_buff *cmdu)
 			cookie = cmdu_clone(cmdu);
 	}
 
-	n = cntlr_find_node(a, cmdu->origin);
-	if (n != NULL) {
-		switch (n->map_profile) {
-			case 3:
-			case 4:
-			case 5:
-			case 6:
-				frag_scheme = CMDU_FRAG_SCHEME_TRUNCATE;
-				break;
-			case 0:
-			case 1:
-			case 2:
-			default:
-				frag_scheme = CMDU_FRAG_SCHEME_TLV_BOUNDARY;
-				break;
+	if (cmdu->datalen >= FRAG_DATA_SIZE) {
+		struct node *n = NULL;
+		int frag_scheme = CMDU_FRAG_SCHEME_BOUNDARY_TLV;
+
+		n = cntlr_find_node(a, cmdu->origin);
+		if (n != NULL) {
+			switch (n->map_profile) {
+				case 3:
+				case 4:
+				case 5:
+				case 6:
+					frag_scheme = CMDU_FRAG_SCHEME_BOUNDARY_OCTET;
+					break;
+				case 0:
+				case 1:
+				case 2:
+				default:
+					frag_scheme = CMDU_FRAG_SCHEME_BOUNDARY_TLV;
+					break;
+			}
 		}
-	}
 
-	cmdu_set_frag_scheme(cmdu->origin, frag_scheme);
+		send_frag_scheme_ubus(a, cmdu->origin, frag_scheme);
+	}
 
 	ret = send_cmdu_ubus(a, cmdu);
 	if (ret < 0) {
-- 
GitLab