Fix end-of-software_load detection (send segment with window number 0, wait for seg_ack)

diff --git a/src/abis_nm.c b/src/abis_nm.c
index 3dd8baf..77a3293 100644
--- a/src/abis_nm.c
+++ b/src/abis_nm.c
@@ -307,6 +307,7 @@
 	int fd;
 	FILE *stream;
 	enum sw_state state;
+	int last_seg;
 };
 
 static struct abis_nm_sw g_sw;
@@ -332,6 +333,22 @@
 	return abis_nm_sendmsg(sw->bts, msg);
 }
 
+static int is_last_line(FILE *stream)
+{
+	char next_seg_buf[256];
+	long pos;
+
+	/* check if we're sending the last line */
+	pos = ftell(stream);
+	if (!fgets(next_seg_buf, sizeof(next_seg_buf)-2, stream)) {
+		fseek(stream, pos, SEEK_SET);
+		return 1;
+	}
+
+	fseek(stream, pos, SEEK_SET);
+	return 0;
+}
+
 /* 6.2.2 / 8.3.2 Load Data Segment */
 static int sw_load_segment(struct abis_nm_sw *sw)
 {
@@ -351,7 +368,13 @@
 			return -EINVAL;
 		}
 		seg_buf[0] = 0x00;
-		seg_buf[1] = 1 + sw->seg_in_window++;
+
+		/* check if we're sending the last line */
+		sw->last_seg = is_last_line(sw->stream);
+		if (sw->last_seg)
+			seg_buf[1] = 0;
+		else
+			seg_buf[1] = 1 + sw->seg_in_window++;
 
 		len = strlen(line_buf) + 2;
 		tlv = msgb_put(msg, TLV_GROSS_LEN(len));
@@ -474,10 +497,8 @@
 		rc = sw_load_segment(sw);
 		if (rc < 0)
 			return rc;
-		if (rc == 1) {
-			sw->state = SW_STATE_WAIT_ENDACK;
-			return sw_load_end(sw);
-		}
+		if (sw->last_seg)
+			break;
 	}
 	return 0;
 }
@@ -501,6 +522,7 @@
 			sw->state = SW_STATE_WAIT_SEGACK;
 			break;
 		case NM_MT_LOAD_INIT_NACK:
+			DEBUGP(DNM, "Software Load Init NACK\n");
 			sw->state = SW_STATE_ERROR;
 			break;
 		}
@@ -509,9 +531,15 @@
 		switch (foh->msg_type) {
 		case NM_MT_LOAD_SEG_ACK:
 			sw->seg_in_window = 0;
-			/* fill window with more segments */
-			rc = sw_fill_window(sw);
-			sw->state = SW_STATE_WAIT_SEGACK;
+			if (!sw->last_seg) {
+				/* fill window with more segments */
+				rc = sw_fill_window(sw);
+				sw->state = SW_STATE_WAIT_SEGACK;
+			} else {
+				/* end the transfer */
+				sw->state = SW_STATE_WAIT_ENDACK;
+				rc = sw_load_end(sw);
+			}
 			break;
 		}
 		break;
@@ -524,6 +552,7 @@
 			rc = sw_activate(sw);
 			break;
 		case NM_MT_LOAD_END_NACK:
+			DEBUGP(DNM, "Software Load End NACK\n");
 			sw->state = SW_STATE_ERROR;
 			break;
 		}
@@ -536,6 +565,7 @@
 			DEBUGP(DMM, "DONE!\n");
 			break;
 		case NM_MT_ACTIVATE_SW_NACK:
+			DEBUGP(DNM, "Activate Software NACK\n");
 			sw->state = SW_STATE_ERROR;
 			break;
 		}
@@ -578,6 +608,22 @@
 	return sw_load_init(sw);
 }
 
+int abis_nm_software_load_status(struct gsm_bts *bts)
+{
+	struct abis_nm_sw *sw = &g_sw;
+	struct stat st;
+	int rc, percent;
+
+	rc = fstat(sw->fd, &st);
+	if (rc < 0) {
+		perror("ERROR during stat");
+		return rc;
+	}
+
+	percent = (ftell(sw->stream) * 100) / st.st_size;
+	return percent;
+}
+
 static void fill_nm_channel(struct abis_nm_channel *ch, u_int8_t bts_port,
 		       u_int8_t ts_nr, u_int8_t subslot_nr)
 {