package gmt.protocol.std;

import gmt.common.util.GmtUtils;
import gmt.protocol.ais.*;
import gmt.protocol.ais.sensor.SensorGPS;
import gmt.protocol.ais.type.IECType;
import gmt.protocol.std.type.BSCType;
import gmt.protocol.std.type.SensorType;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;


public class STDEncoder {
	STD7Msg std7Msg;
	STD8Msg std8Msg;
	List<String> makeMsgList;
	
	public STDEncoder() {
		this.std7Msg = new STD7Msg();
		this.std8Msg = new STD8Msg();
		this.makeMsgList = new ArrayList<String>();
	}
	
	public STD7Msg std7msg() {
		return this.std7Msg;
	}
	
	public STD8Msg std8Msg() {
		return this.std8Msg;
	}
	
	private String makePacketwithCRC(String header, String data) {
		String result = "";
		
		try {
			result = header + GmtUtils.fillString(3, String.valueOf(data.length()), true) + data;
			result = result + "*" + GmtUtils.makeCRC(result);			
		} catch (Exception e) {
			return "";
		}		
		return result;
	}
	
	private GMTResult makeMsg19Dynamic(final AISDecoder aisDecoder, LocalDateTime msgDT, String bsid, LocalDateTime bsUTC, SensorType sensor)
	{
		GMTResult result = new GMTResult();
		try
		{
			Message19 msg19 = aisDecoder.getMsg19();
			
			String s_bsUTC = "";
			String msgType = "";
			LocalDateTime dtUTC;
			
			if(bsUTC.isEqual(GmtUtils.defaultTime())) {
				s_bsUTC = GmtUtils.fillString(14, "", true);			
			} else {
				s_bsUTC = bsUTC.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
			}
			
			/*
			 * 	자선정보인지 확인하여 MessageType 결정
			 */
			if (aisDecoder.getTypeIEC() == IECType.VDO) 
				msgType = "01";
			else
				msgType = "11";
			
			StringBuilder sb = new StringBuilder();
			
			String header  = "";
			String data    = "";
			String extData = "";
			String packet  = "";
			
			/*
			 * 	STD 7.x. Extend 7.x 구성
			 */
			// 7.x Header 부 구성
			header = makeSTD7Header(String.valueOf(sensor.getCode()), "5", String.valueOf(msg19.userid()), msgDT, bsid, msgType);
			
			// Data 부 구성
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 1, "4", true));									// Mode
			sb.append(GmtUtils.fillString( 4, "0", true));                                  // ROT
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg19.sog()), true));          // SOG
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg19.pos_acc()), true));      // PosAcc
			sb.append(GmtUtils.fillString(10, String.valueOf(msg19.longitude()), true));    // Longitude
			sb.append(GmtUtils.fillString( 9, String.valueOf(msg19.latitude()), true));     // Latitude
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg19.cog()), true));          // COG
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg19.true_heading()), true)); // Heading
			
			data = sb.toString();
			
			sb.setLength(0);
			sb.append(data);
			sb.append(GmtUtils.fillString( 1, " ", true));									// Communication state selector flag
			sb.append(GmtUtils.fillString( 1, " ", true));                                  // Sync state
			sb.append(GmtUtils.fillString( 1, " ", true));                                  // Slot timeout
			sb.append(GmtUtils.fillString( 5, " ", true));                                  // sub message
			sb.append(GmtUtils.fillString( 5, " ", true));                                  // Slot increment
			sb.append(GmtUtils.fillString( 1, " ", true));                                  // Number of Slot
			sb.append(GmtUtils.fillString( 5, " ", true));                                  // Slot offset
			sb.append(GmtUtils.fillString( 1, " ", true));                                  // keep flag
			sb.append(GmtUtils.fillString( 2, "15",true));                                  // Navigation status
			sb.append(GmtUtils.fillString( 1, "0", true));                                  // Special manoeuve indicator
			sb.append(GmtUtils.fillString( 1, " ", true));                                  // Class B Unit flag
			sb.append(GmtUtils.fillString( 1, " ", true));                                  // Class B Display flag
			sb.append(GmtUtils.fillString( 1, " ", true));                                  // Class B Band flag
			sb.append(GmtUtils.fillString( 1, " ", true));                                  // Class B Msg22 flag
			sb.append(GmtUtils.fillString( 1, " ", true));                                  // Class B DSC flag
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg19.mode_flag()), true));    // Mode Flag
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg19.raim()), true));         // RAIM Flag
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg19.repeat()), true));       // Repeat indicator
			sb.append(GmtUtils.fillString(14, s_bsUTC, true));                              // Basestation UTC
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg19.utc_sec()), true));      // Time Stamp
			sb.append(GmtUtils.fillString( 3, String.valueOf(msgDT.atZone(ZoneOffset.UTC).toInstant().toEpochMilli()), true));// Rcv Time ms
			
			extData = sb.toString();
			
			// 7.x, Extend 7.x 메시지 구성
		    // Header + Data Length + Data
			packet = makePacketwithCRC(header, data);
			if (!packet.isEmpty()) {
				std7Msg.setMessage1(packet);				
			}
			
			packet = makePacketwithCRC(header, extData);
			if (!packet.isEmpty()) {
				std7Msg.setExtendMsg1(packet);
			}
			
			/*
			 * 	STD 8.x 구성
			 */
			// 8.x Header부 구성
			header = makeSTD8Header(String.valueOf(sensor.getCode()), "5", String.valueOf(msg19.userid()), bsid, msgType, "12", msgDT);
						
			// Data 부 구성
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 1, "0", true));									// Mode
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg19.sog()), true));          // SOG
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg19.pos_acc()), true));      // PosAcc
			sb.append(GmtUtils.fillString(10, String.valueOf(msg19.longitude()), true));    // Longitude
			sb.append(GmtUtils.fillString( 9, String.valueOf(msg19.latitude()), true));     // Latitude
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg19.cog()), true));          // COG
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg19.true_heading()), true)); // Heading
			sb.append(GmtUtils.fillString( 2, "15",true));                                  // Navigation Status
			sb.append(GmtUtils.fillString( 1, " ", true));                                  // PosAcc
			sb.append(GmtUtils.fillString( 1, " ", true));                                  // unit flag
			sb.append(GmtUtils.fillString( 1, " ", true));                                  // band flag
			sb.append(GmtUtils.fillString( 1, " ", true));                                  // msg22_flag
			sb.append(GmtUtils.fillString( 1, " ", true));                                  // dsc_flag
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg19.utc_sec()), true));      // utc_sec
			
			data = sb.toString();
			
			// 8.x 메시지 구성
		    // Header + Data Length + Data
			packet = makePacketwithCRC(header, data);
			if (!packet.isEmpty()) {
				std8Msg.setMessage1(packet);
			}
			
			result.setSuccess(true);
			
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorcode(" Msg19_Dynamic : " +e.getMessage());			
		}
		
		return result;
	}
	
	private GMTResult makeMsg19Static(final AISDecoder aisDecoder, LocalDateTime msgDT, String bsid, SensorType sensor)
	{
		GMTResult result = new GMTResult();
		try
		{
			Message19 msg19 = aisDecoder.getMsg19();
			
			String msgType = "";
			/*
			 * 	자선정보인지 확인하여 MessageType 결정
			 */
			if (aisDecoder.getTypeIEC() == IECType.VDO) 
				msgType = "02";
			else
				msgType = "12";
			
			StringBuilder sb = new StringBuilder();
			
			String header  = "";
			String data    = "";
			String packet  = "";
			String shipName = msg19.name().trim().replace("*", " ");			
			
			header = makeSTD7Header(String.valueOf(sensor.getCode()), "6", String.valueOf(msg19.userid()), msgDT, bsid, msgType);
			
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 9, "0", true));
			sb.append(GmtUtils.fillString(30, shipName, true));
			sb.append(GmtUtils.fillString( 7, " ", true));
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg19.ship_type()), true));
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg19.dim_bow()), true));
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg19.dim_stern()), true));
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg19.dim_port()), true));
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg19.dim_starboard()), true));
			sb.append(GmtUtils.fillString( 4, "0", true));
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg19.pos_type()), true));
			sb.append(GmtUtils.fillString( 8, "00002460", true));			
			sb.append(GmtUtils.fillString(20, " ", true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg19.dte()), true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg19.raim()), true));
			sb.append("9");                 
			sb.append(GmtUtils.fillString( 7, " ", true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg19.repeat()), true));
			sb.append("9");
			
			data = sb.toString();
			
			// 7.x, Extend 7.x 메시지 구성
		    // Header + Data Length + Data
			packet = makePacketwithCRC(header, data);
			if (!packet.isEmpty()) {
				std7Msg.setMessage1(packet);				
			}
			
			/*
			 * 	STD 8.x 구성
			 */
			// 8.x Header부 구성
			header = makeSTD8Header(String.valueOf(sensor.getCode()), "6", String.valueOf(msg19.userid()), bsid, msgType, "12", msgDT);
						
			// Data 부 구성
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 9, "000000000", true));
			sb.append(GmtUtils.fillString(30, shipName, true));
			sb.append(GmtUtils.fillString( 7, " ", true));
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg19.ship_type()), true));
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg19.dim_bow()), true));
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg19.dim_stern()), true));
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg19.dim_port()), true));
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg19.dim_starboard()), true));
			sb.append(GmtUtils.fillString( 4, "0", true));
			sb.append(GmtUtils.fillString(20, " ", true));
			sb.append(GmtUtils.fillString( 8, "00002460", true));
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg19.pos_type()), true));
			sb.append("9");			
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg19.dte()), true));
			
			data = sb.toString();
			
			// 8.x 메시지 구성
		    // Header + Data Length + Data
			packet = makePacketwithCRC(header, data);
			if (!packet.isEmpty()) {
				std8Msg.setMessage1(packet);
			}
		
			result.setSuccess(true);
			
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorcode(" Msg19_Static : " +e.getMessage());
		}
		
		return result;		
	}
	
	
	private LocalDateTime getMsgDT(int utc_Day, int utc_Hour, int utc_Min, int utc_Sec) {
		LocalDateTime ldt = GmtUtils.defaultTime();
		
		try
		{
			LocalDateTime now    = LocalDateTime.now().minusHours(9);
			LocalDateTime preDT  = now.minusHours(1);
			LocalDateTime nextDT = now.plusHours(1);
			
			if (utc_Day == now.getDayOfMonth()) {
				ldt = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), utc_Hour, utc_Min, utc_Sec, 0).plusHours(9); 
			}
			else if (utc_Day == preDT.getDayOfMonth()) {
				ldt = LocalDateTime.of(preDT.getYear(), preDT.getMonth(), preDT.getDayOfMonth(), utc_Hour, utc_Min, utc_Sec, 0).plusHours(9);
			}
			else if (utc_Day == nextDT.getDayOfMonth()) {
				ldt = LocalDateTime.of(nextDT.getYear(), nextDT.getMonth(), nextDT.getDayOfMonth(), utc_Hour, utc_Min, utc_Sec, 0).plusHours(9);
			}			
		} catch(Exception e) {
			return GmtUtils.defaultTime();
		}
		
		return ldt;
	}
	
	public GMTResult encoding(final AISDecoder aisDecoder, LocalDateTime msgDT, String bsid, LocalDateTime bsUTC, BSCType bscType, SensorType sensor)	
	{
		GMTResult result = new GMTResult();
		try
		{
			if (aisDecoder == null) {
				result.setSuccess(false);
				result.setErrorcode("AIS Decoder is not assigned");
				return result;
			}
			
			std7Msg.clear();
			std8Msg.clear();
			
			switch(aisDecoder.getMessageID()) 
			{
				case(1) : result = encodeMsg01(aisDecoder, msgDT, bsid, bsUTC, sensor); break;
				case(2) : result = encodeMsg02(aisDecoder, msgDT, bsid, bsUTC, sensor); break;
				case(3) : result = encodeMsg03(aisDecoder, msgDT, bsid, bsUTC, sensor); break;
				case(5) : result = encodeMsg05(aisDecoder, msgDT, bsid, sensor);        break;
				case(8) : {
					if (aisDecoder.getDAC() == 1 && aisDecoder.getFI() == 0) {
						result = encodeMsg08(aisDecoder, msgDT, bsid, sensor);
					} else {
						result.setSuccess(true);
					}
				}
					break;
				case(9) : result = encodeMsg09(aisDecoder, msgDT, bsid, bsUTC, sensor); break;
				case(12) : result = encodeMsg12(aisDecoder, msgDT, bsid, sensor);		break;
				case(14) : result = encodeMsg13(aisDecoder, msgDT, bsid, sensor);		break;
				case(18) : result = encodeMsg18(aisDecoder, msgDT, bsid, bsUTC, sensor);break;
				case(19) : result = encodeMsg19(aisDecoder, msgDT, bsid, bsUTC, sensor);break;
				case(21) : result = encodeMsg21(aisDecoder, msgDT, bsid, bsUTC, sensor);break;
				case(24) : result = encodeMsg24(aisDecoder, msgDT, bsid, sensor);		break;
				case(27) : result = encodeMsg27(aisDecoder, msgDT, bsid, bsUTC, sensor);break;
				default  : result.setSuccess(true); break;
			}			
			
		} catch (Exception e) {
			result.setErrorcode("STDConvert encoding fail : "+ e.getMessage());
		}
		
		return result;
	}
	
	
	public String makeSTD7Header(String targetSensor, String packetID, String shipID, LocalDateTime dt, String areaID, String messageType) {
		StringBuilder sb = new StringBuilder();
		
		sb.append("$");
		sb.append(GmtUtils.fillString( 2, targetSensor, true));
		sb.append(GmtUtils.fillString( 1, packetID, 	true));
		sb.append(GmtUtils.fillString(12, shipID, 		true));
		sb.append(GmtUtils.fillString(14, dt.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")), true));
		sb.append(GmtUtils.fillString( 9, areaID, 		true));
		sb.append(GmtUtils.fillString( 2, messageType, 	true));
		
		return sb.toString();
	}
	
	public String makeSTD7Header(String targetSensor, String packetID, String shipID, LocalDateTime dt, String areaID, String messageType, String targetType) {
		
		StringBuilder sb = new StringBuilder();		
		sb.append(makeSTD7Header(targetSensor, packetID, shipID, dt, areaID, messageType));
		sb.append(GmtUtils.fillString(2, targetType, true));	
		
		return sb.toString();
	}
	
	public String makeSTD8Header(String targetSensor, String packetID, String shipID, String bsid, String msgType, String targetType, LocalDateTime dt)
	{
		StringBuilder sb = new StringBuilder();
		sb.append("$");
		sb.append(GmtUtils.fillString( 2, targetSensor, true));
		sb.append(GmtUtils.fillString( 1, packetID, 	true));
		sb.append(GmtUtils.fillString(12, shipID, 		true));
		sb.append(GmtUtils.fillString(14, dt.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")), true));
		sb.append(GmtUtils.fillString( 9, bsid, 		true));
		sb.append(GmtUtils.fillString( 2, msgType, 		true));
		sb.append(GmtUtils.fillString( 2, targetType, 	true));
				
		return sb.toString();				
	}
	
	
	public GMTResult encodeMsg01(final AISDecoder aisDecoder, LocalDateTime msgDT, String bsid, LocalDateTime bsUTC, SensorType sensor) {
		GMTResult result = new GMTResult();
		try
		{
			StringBuilder sb = new StringBuilder();
			
			String header  = "";
			String data    = "";
			String extData = "";
			String packet  = "";
			
			String strBSUTC;
			LocalDateTime dtUTC;
			
			String subMsg  = "";
			String offset  = "";
			String msgType = "";
			
			int iHour   = 24;
			int iMinute = 60;
			
			
			if(bsUTC.isEqual(GmtUtils.defaultTime())) {
				strBSUTC = GmtUtils.fillString(14, "", true);			
			} else {
				strBSUTC = bsUTC.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
			}
			
			//communication state sub message 처리
			switch(aisDecoder.getMsg01().slot_timeout())
			{
				case(0) :
					subMsg = "     ";
					offset = String.valueOf(aisDecoder.getMsg01().sub_message());
					break;
				
				case(1) :	//UTC (HHMM)
					iHour = aisDecoder.getMsg01().sub_message() >> 9;
					if (iHour >= 24) {
						iHour = 24;
					} else {
						iHour = iHour + 9;
						if (iHour > 24) { iHour = iHour - 24; }
					}
					
					iMinute = (aisDecoder.getMsg01().sub_message() >> 2) & 0x7F;
					if (iMinute > 60)
						iMinute = 60;
					
					subMsg = " " + GmtUtils.fillString(3, String.valueOf(iHour), true)		// UTC Hour
								 + GmtUtils.fillString(3, String.valueOf(iMinute), true); 	// UTC Minute
					break;
				
				case(2) :
				case(4) :
				case(6) :	// Slot number used for transmission
					if (aisDecoder.getMsg01().sub_message() > 2249) {
						subMsg = "     ";
					} else {
						subMsg = GmtUtils.fillString(5, String.valueOf(aisDecoder.getMsg01().sub_message()), true);
					}
					break;
				
				case(3) :
				case(5) :
				case(7) :	// Number of other station
					if (aisDecoder.getMsg01().sub_message() > 16383) {
						subMsg = "     ";
					} else {
						subMsg = GmtUtils.fillString(5, String.valueOf(aisDecoder.getMsg01().sub_message()), true);
					}
					break;
					
				default : subMsg = "     ";				
			}
			
			/*
			 * 자선정보인지 확인하여 MessageType 결정
			 */
			if (aisDecoder.getTypeIEC().equals(IECType.VDO)) 
				msgType = "01";
			else	
				msgType = "11";
			
			/*
			 * 	STD 7.x. Extend 7.x 구성
			 */
			header = makeSTD7Header(String.valueOf(sensor.getCode()), 
									"5", 
									String.valueOf(aisDecoder.getMsg01().userid()), 
									msgDT, 
									bsid, 
									msgType);
			
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 1, "1", true));													// Mode
			sb.append(GmtUtils.fillString( 4, String.valueOf(aisDecoder.getMsg01().rot()), true));          // ROT
			sb.append(GmtUtils.fillString( 4, String.valueOf(aisDecoder.getMsg01().sog()), true));          // SOG
			sb.append(GmtUtils.fillString( 1, String.valueOf(aisDecoder.getMsg01().pos_acc()), true));      // PosAcc
			sb.append(GmtUtils.fillString(10, String.valueOf(aisDecoder.getMsg01().longitude()), true));    // Longitude
			sb.append(GmtUtils.fillString( 9, String.valueOf(aisDecoder.getMsg01().latitude()), true));     // Latitude
			sb.append(GmtUtils.fillString( 4, String.valueOf(aisDecoder.getMsg01().cog()), true));          // COG
			sb.append(GmtUtils.fillString( 3, String.valueOf(aisDecoder.getMsg01().true_heading()), true));	// Heading	
			
			data = sb.toString();
			
			sb.setLength(0);
			sb.append(data);
			sb.append(GmtUtils.fillString( 1, "0", true));															// Communication state selector flag (AIS Msg1 = SOTDMA)
			sb.append(GmtUtils.fillString( 1, String.valueOf(aisDecoder.getMsg01().sync_state()), true));           // Sync state
			sb.append(GmtUtils.fillString( 1, String.valueOf(aisDecoder.getMsg01().slot_timeout()), true));         // Slot timeout
			sb.append(GmtUtils.fillString( 5, subMsg, true));                                                       // sub message
			sb.append(GmtUtils.fillString( 5, " ", true));                                                          // Slot increment
			sb.append(GmtUtils.fillString( 1, " ", true));                                                          // Number of slot
			sb.append(GmtUtils.fillString( 5, offset, true));                                                       // Slot offset
			sb.append(GmtUtils.fillString( 1, " ", true));                                                          // Keep Flag
			sb.append(GmtUtils.fillString( 2, String.valueOf(aisDecoder.getMsg01().nav_status()), true));           // Navigation Status
			sb.append(GmtUtils.fillString( 1, String.valueOf(aisDecoder.getMsg01().special_manoeuvre()), true));    // Sepcial manoeuvre indicator
			sb.append(GmtUtils.fillString( 1, " ", true));                                                          // Class B Unit flag
			sb.append(GmtUtils.fillString( 1, " ", true));                                                          // Class B Display flag
			sb.append(GmtUtils.fillString( 1, " ", true));                                                          // Class B Band Flag
			sb.append(GmtUtils.fillString( 1, " ", true));                                                          // Class B Msg22 Flag
			sb.append(GmtUtils.fillString( 1, " ", true));                                                          // Class B DSC Flag
			sb.append(GmtUtils.fillString( 1, " ", true));                                                          // Mode Flag
			sb.append(GmtUtils.fillString( 1, String.valueOf(aisDecoder.getMsg01().raim()), true));                 // RAIM Flag
			sb.append(GmtUtils.fillString( 1, String.valueOf(aisDecoder.getMsg01().repeat()), true));               // Repeat indicator
			sb.append(GmtUtils.fillString(14, strBSUTC, true));                                                     // Basestation UTC
			sb.append(GmtUtils.fillString( 2, String.valueOf(aisDecoder.getMsg01().utc_sec()), true));              // Time Stamp
			sb.append(GmtUtils.fillString( 3, String.valueOf(msgDT.atZone(ZoneOffset.UTC).toInstant().toEpochMilli()), true));// Rcv Time ms
			
			extData = sb.toString();
			
			// 7.x, Extend 7.x 메시지 구성
		    // Header + Data Length + Data
			packet = header + GmtUtils.fillString(3, data, true) + data;
			std7Msg.setMessage1(packet + "*"+ GmtUtils.makeCRC(packet));
			
			packet = header + GmtUtils.fillString(3, extData, true) + extData;
			std7Msg.setExtendMsg1(packet + "*"+ GmtUtils.makeCRC(packet)); 
			///////////////////////////////////////////////////////////////////////////////////////////////////////////
			
			/*
			 * 	STD 8.x 구성
			 */			
			// 8.x Header부 구성
			header = makeSTD8Header(String.valueOf(sensor.getCode()), 
									"5", 
									String.valueOf(aisDecoder.getMsg01().userid()), 
									bsid, 
									msgType, 
									"11", 
									msgDT);
			
			// 8.x Data 부 구성
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 1, "0", true));													
			sb.append(GmtUtils.fillString( 4, String.valueOf(aisDecoder.getMsg01().rot()), true));          
			sb.append(GmtUtils.fillString( 4, String.valueOf(aisDecoder.getMsg01().sog()), true));          
			sb.append(GmtUtils.fillString( 1, String.valueOf(aisDecoder.getMsg01().pos_acc()), true));      
			sb.append(GmtUtils.fillString(10, String.valueOf(aisDecoder.getMsg01().longitude()), true));    
			sb.append(GmtUtils.fillString( 9, String.valueOf(aisDecoder.getMsg01().latitude()), true));     
			sb.append(GmtUtils.fillString( 4, String.valueOf(aisDecoder.getMsg01().cog()), true));          
			sb.append(GmtUtils.fillString( 3, String.valueOf(aisDecoder.getMsg01().true_heading()), true));	
			sb.append(GmtUtils.fillString( 2, String.valueOf(aisDecoder.getMsg01().nav_status()), true));	
			sb.append(GmtUtils.fillString( 2, String.valueOf(aisDecoder.getMsg01().utc_sec()), true));
			
			data = sb.toString();
			
			// 8.x 메시지 구성
		    // Header + Data Length + Data
			packet = header + GmtUtils.fillString(3, String.valueOf(data.length()), true) + data;
			std8Msg.setMessage1(packet + "*"+ GmtUtils.makeCRC(packet)); 
			
			///////////////////////////////////////////////////////////////////////////////////////////////////////////
			
			result.setSuccess(true);
			
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorcode("Msg01 : "+ e.getMessage());
		}
		
		return result;
	}
	
	public GMTResult encodeMsg02(final AISDecoder aisDecoder, LocalDateTime msgDT, String bsid, LocalDateTime bsUTC, SensorType sensor) {
		GMTResult result = new GMTResult();
		try
		{
			StringBuilder sb = new StringBuilder();
			
			if (aisDecoder == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg02 : AIS Decoder is not assigned");
				return result;
			}
			
			Message02 msg02 = aisDecoder.getMsg02();
			if (msg02 == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg02 : AIS Message02 is not assigned");
				return result;
			}
			
			String header  = "";
			String data    = "";
			String extData = "";
			String packet  = "";
			
			String strBSUTC;
			LocalDateTime dtUTC;
			
			String subMsg  = "";
			String offset  = "";
			String msgType = "";
			
			int iHour   = 24;
			int iMinute = 60;
			
			
			if(bsUTC.isEqual(GmtUtils.defaultTime())) {
				strBSUTC = GmtUtils.fillString(14, "", true);			
			} else {
				strBSUTC = bsUTC.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
			}
			
			//communication state sub message 처리
			switch(msg02.slot_timeout())
			{
				case(0) :
					subMsg = "     ";
					offset = String.valueOf(msg02.sub_message());
					break;
				
				case(1) :	//UTC (HHMM)
					iHour = msg02.sub_message() >> 9;
					if (iHour >= 24) {
						iHour = 24;
					} else {
						iHour = iHour + 9;
						if (iHour > 24) { iHour = iHour - 24; }
					}
					
					iMinute = (msg02.sub_message() >> 2) & 0x7F;
					if (iMinute > 60)
						iMinute = 60;
					
					subMsg = " " + GmtUtils.fillString(3, String.valueOf(iHour), true)		// UTC Hour
								 + GmtUtils.fillString(3, String.valueOf(iMinute), true); 	// UTC Minute
					break;
				
				case(2) :
				case(4) :
				case(6) :	// Slot number used for transmission
					if (msg02.sub_message() > 2249) {
						subMsg = "     ";
					} else {
						subMsg = GmtUtils.fillString(5, String.valueOf(msg02.sub_message()), true);
					}
					break;
				
				case(3) :
				case(5) :
				case(7) :	// Number of other station
					if (msg02.sub_message() > 16383) {
						subMsg = "     ";
					} else {
						subMsg = GmtUtils.fillString(5, String.valueOf(msg02.sub_message()), true);
					}
					break;
					
				default : subMsg = "     ";				
			}
			
			/*
			 * 자선정보인지 확인하여 MessageType 결정
			 */
			if (aisDecoder.getTypeIEC().equals(IECType.VDO)) 
				msgType = "01";
			else	
				msgType = "11";
			
			/*
			 * 	STD 7.x. Extend 7.x 구성
			 */
			header = makeSTD7Header(String.valueOf(sensor.getCode()), 
									"5", 
									String.valueOf(msg02.userid()), 
									msgDT, 
									bsid, 
									msgType);
			
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 1, "2", true));									// Mode
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg02.rot()), true));          // ROT
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg02.sog()), true));          // SOG
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg02.pos_acc()), true));      // PosAcc
			sb.append(GmtUtils.fillString(10, String.valueOf(msg02.longitude()), true));    // Longitude
			sb.append(GmtUtils.fillString( 9, String.valueOf(msg02.latitude()), true));     // Latitude
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg02.cog()), true));          // COG
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg02.true_heading()), true));	// Heading	
			
			data = sb.toString();
			
			sb.setLength(0);
			sb.append(data);
			sb.append(GmtUtils.fillString( 1, "0", true));											// Communication state selector flag (AIS Msg1 = SOTDMA)
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg02.sync_state()), true));           // Sync state
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg02.slot_timeout()), true));         // Slot timeout
			sb.append(GmtUtils.fillString( 5, subMsg, true));                                       // sub message
			sb.append(GmtUtils.fillString( 5, " ", true));                                          // Slot increment
			sb.append(GmtUtils.fillString( 1, " ", true));                                          // Number of slot
			sb.append(GmtUtils.fillString( 5, offset, true));                                       // Slot offset
			sb.append(GmtUtils.fillString( 1, " ", true));                                          // Keep Flag
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg02.nav_status()), true));           // Navigation Status
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg02.special_manoeuvre()), true));    // Sepcial manoeuvre indicator
			sb.append(GmtUtils.fillString( 1, " ", true));                                          // Class B Unit flag
			sb.append(GmtUtils.fillString( 1, " ", true));                                          // Class B Display flag
			sb.append(GmtUtils.fillString( 1, " ", true));                                          // Class B Band Flag
			sb.append(GmtUtils.fillString( 1, " ", true));                                          // Class B Msg22 Flag
			sb.append(GmtUtils.fillString( 1, " ", true));                                          // Class B DSC Flag
			sb.append(GmtUtils.fillString( 1, " ", true));                                          // Mode Flag
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg02.raim()), true));                 // RAIM Flag
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg02.repeat()), true));               // Repeat indicator
			sb.append(GmtUtils.fillString(14, strBSUTC, true));                                     // Basestation UTC
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg02.utc_sec()), true));              // Time Stamp
			sb.append(GmtUtils.fillString( 3, String.valueOf(msgDT.atZone(ZoneOffset.UTC).toInstant().toEpochMilli()), true));// Rcv Time ms
			
			extData = sb.toString();
			
			// 7.x, Extend 7.x 메시지 구성
		    // Header + Data Length + Data
			packet = header + GmtUtils.fillString(3, data, true) + data;
			std7Msg.setMessage1(packet + "*"+ GmtUtils.makeCRC(packet));
			
			packet = header + GmtUtils.fillString(3, extData, true) + extData;
			std7Msg.setExtendMsg1(packet + "*"+ GmtUtils.makeCRC(packet)); 
			///////////////////////////////////////////////////////////////////////////////////////////////////////////
			
			/*
			 * 	STD 8.x 구성
			 */			
			// 8.x Header부 구성
			header = makeSTD8Header(String.valueOf(sensor.getCode()), 
									"5", 
									String.valueOf(msg02.userid()), 
									bsid, 
									msgType, 
									"11", 
									msgDT);
			
			// 8.x Data 부 구성
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 1, "0", true));													
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg02.rot()), true));          
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg02.sog()), true));          
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg02.pos_acc()), true));      
			sb.append(GmtUtils.fillString(10, String.valueOf(msg02.longitude()), true));    
			sb.append(GmtUtils.fillString( 9, String.valueOf(msg02.latitude()), true));     
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg02.cog()), true));          
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg02.true_heading()), true));	
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg02.nav_status()), true));	
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg02.utc_sec()), true));
			
			data = sb.toString();
			
			// 8.x 메시지 구성
		    // Header + Data Length + Data
			packet = header + GmtUtils.fillString(3, String.valueOf(data.length()), true) + data;
			std8Msg.setMessage1(packet + "*"+ GmtUtils.makeCRC(packet)); 
			
			///////////////////////////////////////////////////////////////////////////////////////////////////////////
			
			result.setSuccess(true);
			
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorcode("Msg02 : "+ e.getMessage());
		}
		
		return result;
	}
	
	public GMTResult encodeMsg03(final AISDecoder aisDecoder, LocalDateTime msgDT, String bsid, LocalDateTime bsUTC, SensorType sensor) {
		GMTResult result = new GMTResult();
		try
		{
			StringBuilder sb = new StringBuilder();
			
			if (aisDecoder == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg03 : AIS Decoder is not assigned");
				return result;
			}
			
			Message03 msg03 = aisDecoder.getMsg03();
			if (msg03 == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg03 : AIS Message02 is not assigned");
				return result;
			}
			
			String header  = "";
			String data    = "";
			String extData = "";
			String packet  = "";
			
			String strBSUTC;
			LocalDateTime dtUTC;

			String offset  = "";
			String msgType = "";
			
			if(bsUTC.isEqual(GmtUtils.defaultTime())) {
				strBSUTC = GmtUtils.fillString(14, "", true);			
			} else {
				strBSUTC = bsUTC.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
			}
			
			//Slot offset 추출
			if (msg03.num_slots() >= 5 && msg03.num_slots() <= 7)
				offset = String.valueOf(msg03.num_slots() + 8192);
			else
				offset = "     ";
						
			/*
			 * 자선정보인지 확인하여 MessageType 결정
			 */
			if (aisDecoder.getTypeIEC().equals(IECType.VDO)) 
				msgType = "01";
			else	
				msgType = "11";
			
			/*
			 * 	STD 7.x. Extend 7.x 구성
			 */
			header = makeSTD7Header(String.valueOf(sensor.getCode()), 
									"5", 
									String.valueOf(msg03.userid()), 
									msgDT, 
									bsid, 
									msgType);
			
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 1, "3", true));									// Mode
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg03.rot()), true));          // ROT
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg03.sog()), true));          // SOG
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg03.pos_acc()), true));      // PosAcc
			sb.append(GmtUtils.fillString(10, String.valueOf(msg03.longitude()), true));    // Longitude
			sb.append(GmtUtils.fillString( 9, String.valueOf(msg03.latitude()), true));     // Latitude
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg03.cog()), true));          // COG
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg03.true_heading()), true));	// Heading	
			
			data = sb.toString();
			
			sb.setLength(0);
			sb.append(data);
			sb.append(GmtUtils.fillString(  1, "1", true));											// Communication state selector flag (AIS Msg3 = ITDMA)
			sb.append(GmtUtils.fillString(  1, String.valueOf(msg03.sync_state()), true));          // Sync state
			sb.append(GmtUtils.fillString(  1, " ", true));         				                // Slot timeout
			sb.append(GmtUtils.fillString(  5, " ", true));                                         // Communication state sub message
			sb.append(GmtUtils.fillString(  5, String.valueOf(msg03.slot_increment()), true));      // Slot increment
			sb.append(GmtUtils.fillString(  1, String.valueOf(msg03.num_slots()), true));           // Number of Slot
			sb.append(GmtUtils.fillString(  5, offset, true));                                      // Slot offset
			sb.append(GmtUtils.fillString(  1, String.valueOf(msg03.keep()), true));                // Keep Flag
			sb.append(GmtUtils.fillString(  2, String.valueOf(msg03.nav_status()), true));          // Navigation Status
			sb.append(GmtUtils.fillString(  1, String.valueOf(msg03.special_manoeuvre()), true));   // Sepcial manoeuvre indicator
			sb.append(GmtUtils.fillString(  1, " ", true));                                         // Class B Unit flag
			sb.append(GmtUtils.fillString(  1, " ", true));                                         // Class B Display flag
			sb.append(GmtUtils.fillString(  1, " ", true));                                         // Class B Band Flag
			sb.append(GmtUtils.fillString(  1, " ", true));                                         // Class B Msg22 Flag
			sb.append(GmtUtils.fillString(  1, " ", true));                                         // Class B DSC Flag
			sb.append(GmtUtils.fillString(  1, "0", true));                                         // Mode Flag
			sb.append(GmtUtils.fillString(  1, String.valueOf(msg03.raim()), true));                // RAIM Flag
			sb.append(GmtUtils.fillString(  1, String.valueOf(msg03.repeat()), true));              // Repeat indicator
			sb.append(GmtUtils.fillString( 14, strBSUTC, true));                                    // Basestation UTC
			sb.append(GmtUtils.fillString(  2, String.valueOf(msg03.utc_sec()), true));             // Time Stamp
			sb.append(GmtUtils.fillString(  3, String.valueOf(msgDT.atZone(ZoneOffset.UTC).toInstant().toEpochMilli()), true));// Rcv Time ms
			
			extData = sb.toString();
			
			// 7.x, Extend 7.x 메시지 구성
		    // Header + Data Length + Data
			packet = header + GmtUtils.fillString(3, String.valueOf(data.length()), true) + data;
			std7Msg.setMessage1(packet + "*"+ GmtUtils.makeCRC(packet));
			
			packet = header + GmtUtils.fillString(3, String.valueOf(extData.length()), true) + extData;
			std7Msg.setExtendMsg1(packet + "*"+ GmtUtils.makeCRC(packet)); 
			///////////////////////////////////////////////////////////////////////////////////////////////////////////
			
			/*
			 * 	STD 8.x 구성
			 */			
			// 8.x Header부 구성
			header = makeSTD8Header(String.valueOf(sensor.getCode()), 
									"5", 
									String.valueOf(msg03.userid()), 
									bsid, 
									msgType, 
									"11", 
									msgDT);
			
			// 8.x Data 부 구성
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 1, "0", true));													
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg03.rot()), true));          
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg03.sog()), true));          
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg03.pos_acc()), true));      
			sb.append(GmtUtils.fillString(10, String.valueOf(msg03.longitude()), true));    
			sb.append(GmtUtils.fillString( 9, String.valueOf(msg03.latitude()), true));     
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg03.cog()), true));          
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg03.true_heading()), true));	
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg03.nav_status()), true));	
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg03.utc_sec()), true));
			
			data = sb.toString();
			
			// 8.x 메시지 구성
		    // Header + Data Length + Data
			packet = header + GmtUtils.fillString(3, String.valueOf(data.length()), true) + data;
			std8Msg.setMessage1(packet + "*"+ GmtUtils.makeCRC(packet)); 
			
			///////////////////////////////////////////////////////////////////////////////////////////////////////////
			
			result.setSuccess(true);
			
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorcode("Msg03 : "+ e.getMessage());
		}
		
		return result;
	}
	
	public GMTResult encodeMsg05(final AISDecoder aisDecoder, LocalDateTime msgDT, String bsid, SensorType sensor) {
		GMTResult result = new GMTResult();
		try
		{
			StringBuilder sb = new StringBuilder();
			
			if (aisDecoder == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg05 : AIS Decoder is not assigned");
				return result;
			}
			
			Message05 msg05 = aisDecoder.getMsg05();
			if (msg05 == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg05 : AIS Message04 is not assigned");
				return result;
			}
			
			String header  = "";
			String data    = "";			
			String packet  = "";			
			
			String msgType  = "";
			String shipName = "";
			String dest     = "";
			
			/*
			 * 자선정보인지 확인하여 MessageType 결정
			 */
			if (aisDecoder.getTypeIEC().equals(IECType.VDO)) 
				msgType = "02";
			else	
				msgType = "12";
			
			/*
			 * 	STD 7.x. Extend 7.x 구성
			 */
			header = makeSTD7Header(String.valueOf(sensor.getCode()), 
									"6", 
									String.valueOf(msg05.userid()), 
									msgDT, 
									bsid, 
									msgType);
			
			shipName = msg05.name().trim().replace("*", " ");
			dest     = msg05.dest().trim().replace("*", " ");
			
			sb.setLength(0);
			
			if (msg05.imo() == 0) {
				sb.append(GmtUtils.fillString(9, " ", true));				
			} else {
				sb.append(GmtUtils.fillString(9, String.valueOf(msg05.imo()), true));
			}
			
			sb.append(GmtUtils.fillString(30, shipName, true));
			
			if (msg05.callsign() == "0000000") {
				sb.append(GmtUtils.fillString(7, "", true));
			} else {
				sb.append(GmtUtils.fillString(7, msg05.callsign(), true));
			}
			
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg05.ship_type()), true));
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg05.dim_bow()), true));
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg05.dim_stern()), true));
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg05.dim_port()), true));
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg05.dim_starboard()), true));
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg05.draught()), true));
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg05.pos_type()), true));
			sb.append(GmtUtils.fillString( 8, msg05.eta_str(), true));
			sb.append(GmtUtils.fillString(20, dest, true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg05.dte()), true));
			sb.append("0");                 
			sb.append("9");                 
			sb.append(GmtUtils.fillString( 7, " ", true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg05.repeat()), true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg05.version()), true));
			
			data = sb.toString();
			
			// 7.x, Extend 7.x 메시지 구성
		    // Header + Data Length + Data
			packet = header + GmtUtils.fillString(3, data, true) + data;
			std7Msg.setMessage1(packet + "*"+ GmtUtils.makeCRC(packet));
			std7Msg.setExtendMsg1(std7Msg.getMessage1());
			 
			///////////////////////////////////////////////////////////////////////////////////////////////////////////
			
			/*
			 * 	STD 8.x 구성
			 */			
			// 8.x Header부 구성
			header = makeSTD8Header(String.valueOf(sensor.getCode()), 
									"6", 
									String.valueOf(msg05.userid()), 
									bsid, 
									msgType, 
									" ", 
									msgDT);
			
			// 8.x Data 부 구성
			sb.setLength(0);
			
			if (msg05.imo() == 0) {
				sb.append(GmtUtils.fillString(9, " ", true));				
			} else {
				sb.append(GmtUtils.fillString(9, String.valueOf(msg05.imo()), true));
			}
			
			sb.append(GmtUtils.fillString(30, shipName, true));
			
			if (msg05.callsign() == "0000000") {
				sb.append(GmtUtils.fillString(7, "", true));
			} else {
				sb.append(GmtUtils.fillString(7, msg05.callsign(), true));
			}
			
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg05.ship_type()), true));
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg05.dim_bow()), true));
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg05.dim_stern()), true));
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg05.dim_port()), true));
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg05.dim_starboard()), true));
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg05.draught()), true));
			sb.append(GmtUtils.fillString(20, dest, true));
			sb.append(GmtUtils.fillString( 8, String.valueOf(msg05.eta_str()), true));
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg05.pos_type()), true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg05.version()), true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg05.dte()), true));
			
			data = sb.toString();
			
			
			// 8.x 메시지 구성
		    // Header + Data Length + Data
			packet = header + GmtUtils.fillString(3, String.valueOf(data.length()), true) + data;
			std8Msg.setMessage1(packet + "*"+ GmtUtils.makeCRC(packet)); 
			
			///////////////////////////////////////////////////////////////////////////////////////////////////////////
			
			result.setSuccess(true);
			
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorcode("Msg05 : "+ e.getMessage());
		}
		
		return result;
	}
	
	public GMTResult encodeMsg06_SensorInfo(final AISDecoder aisDecoder, String bsid) {
		GMTResult result = new GMTResult();
		
		try
		{	
			if (aisDecoder == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg06_SensorInfo : AIS Decoder is not assigned");
				return result;
			}
			
			Message06_440_41 msgSensor = aisDecoder.getMsg06_440_41();
			if (msgSensor == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg06_SensorInfo : AIS Message04 is not assigned");
				return result;
			}
			
			StringBuilder sb = new StringBuilder();
			
			this.makeMsgList.clear();
			int idx   = 0;
			int count = 0;
			
			String header = "";
			String data   = "";
			String packet = "";
			
			LocalDateTime msgDT;
			
			count = msgSensor.sensor_gps_cnt();
			for (int i = 0; i < count; i++) {
				SensorGPS gps = msgSensor.sensor_gps(i);
				
				msgDT = getMsgDT(gps.utcDay(), gps.utcHour(), gps.utcMinute(), gps.utcSecond());
				
				// Header 부 구성
				header = makeSTD7Header("83", 
										"2", 
										String.valueOf(msgSensor.userid()), 
										LocalDateTime.now(), 
										bsid, 
										"1");
				if (header.equals(""))
					continue;
				
				// Data 부 구성
				sb.setLength(0);
				sb.append("0"); sb.append("|");				                                             //구분
				sb.append("1"); sb.append("|");                                                          //통신망
				sb.append(msgDT.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); sb.append("|");  //센서시각
				sb.append("");  sb.append("|");                                                          //ReqID
				sb.append("");  sb.append("|");                                                          //시작시간
				sb.append(String.valueOf(gps.latitude()));  sb.append("|");                              //Latitude
				sb.append(String.valueOf(gps.longitude())); sb.append("|");                              //Longitude
				sb.append(String.valueOf(gps.sog() / 10));  sb.append("|");                              //SOG
				sb.append(String.valueOf(gps.cog() / 10));  sb.append("|");                              //SOG
				sb.append(String.valueOf(gps.qulity()));                                                 //GPS Qulity Indicator
				
				packet = header + GmtUtils.fillString(3, String.valueOf(data.length()), true) + data;	
				packet = packet +"*"+ GmtUtils.makeCRC(packet);
				
				makeMsgList.add(packet);
			}
			
			
			
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorcode("Msg06_SensorInfo : "+ e.getMessage());
		}
		
		return result;
	}
	
	
	public GMTResult encodeMsg07(final AISDecoder aisDecoder, LocalDateTime msgDT, String bsid, SensorType sensor) {
		GMTResult result = new GMTResult();
		
		try
		{
			if (aisDecoder == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg07 : AIS Decoder is not assigned");
				return result;
			}
			
			Message07 msg07 = aisDecoder.getMsg07();
			if (msg07 == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg07 : AIS Message07 is not assigned");
				return result;
			}
			
			StringBuilder sb = new StringBuilder();
			
			String header = "";
			String data   = "";
			String packet = "";
			/*
			 *  STD 8.x 구성
			 */
			// 8.x Header부 구성
			header = makeSTD8Header(String.valueOf(sensor.getCode()), 
					"7", 
					String.valueOf(msg07.userid()), 
					bsid, 
					"52", 
					"00", 
					msgDT);
		
			// 8.x Data 부 구성
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 2, " 7", true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg07.repeat()), true));
			sb.append(GmtUtils.fillString(12, String.valueOf(msg07.destid_1()), true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg07.sequence_1()), true));
			sb.append(GmtUtils.fillString(12, String.valueOf(msg07.destid_2()), true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg07.sequence_2()), true));
			sb.append(GmtUtils.fillString(12, String.valueOf(msg07.destid_3()), true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg07.sequence_3()), true));
			sb.append(GmtUtils.fillString(12, String.valueOf(msg07.destid_4()), true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg07.sequence_4()), true));
			
			data = sb.toString();
			
			packet = makePacketwithCRC(header, data).trim();
			if (!packet.isEmpty())
				std8Msg.setMessage1(packet);
			
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorcode("Msg07 : "+ e.getMessage());
		}
		
		return result;
	}
	
	public GMTResult encodeMsg08(final AISDecoder aisDecoder, LocalDateTime msgDT, String bsid, SensorType sensor) {
		GMTResult result = new GMTResult();
		
		try
		{
			if (aisDecoder == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg08 : AIS Decoder is not assigned");
				return result;
			}
			
			Message08 msg08 = aisDecoder.getMsg08();
			if (msg08 == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg08 : AIS Message08 is not assigned");
				return result;
			}
			
			StringBuilder sb = new StringBuilder();
			
			String header = "";
			String data   = "";
			String packet = "";
			/*
			 *  STD 7.x. Extend 7.x 구성
			 */
			// 7.x Header 부 구성
			
			header = makeSTD7Header(String.valueOf(sensor.getCode()), 
									"7", 
									String.valueOf(msg08.userid()), 
									msgDT, 
									bsid, 
									"22");
			// Data 부 구성
			sb.setLength(0);
			sb.append(GmtUtils.fillString(2, " ", true));
			sb.append(GmtUtils.fillString(1, "1", true));
			sb.append(GmtUtils.fillString(1, "0", true));
			sb.append(GmtUtils.fillString(12, String.valueOf(msg08.userid()), true));
			
//			int len = msg08.
			
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorcode("");
		}
		
		return result;		
	}
	
	
	public GMTResult encodeMsg09(final AISDecoder aisDecoder, LocalDateTime msgDT, String bsid, LocalDateTime bsUTC, SensorType sensor)
	{
		GMTResult result = new GMTResult();
		
		try
		{
			if (aisDecoder == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg09 : AIS Decoder is not assigned");
				return result;
			}
			
			Message09 msg09 = aisDecoder.getMsg09();
			if (msg09 == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg09 : AIS Message08 is not assigned");
				return result;
			}
			
			
			LocalDateTime dtUTC;
			String s_bsUTC		= "";
			String syncState 	= "";
			String slotTimeOut 	= "";
			String subMsg 		= "";
			String offset 		= "";
			String slotInc 		= "";
			String numberOfSlot = "";
			String keepFlag 	= "";
			String msgType 		= "";
			
			if(bsUTC.isEqual(GmtUtils.defaultTime())) {
				s_bsUTC = GmtUtils.fillString(14, "", true);			
			} else {
				s_bsUTC = bsUTC.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
			}
			
			switch(msg09.comm_state()) {
			case(0) :	//SOTDMA
				syncState = GmtUtils.fillString(1, String.valueOf(msg09.sotdma_state().sync_state()), true);
				slotTimeOut = GmtUtils.fillString(1, String.valueOf(msg09.sotdma_state().slot_timeout()), true);
				
				//communication state sub message 처리
				switch(msg09.sotdma_state().slot_timeout()) {
					case(0) :
						subMsg = "     ";
						offset = String.valueOf(msg09.sotdma_state().sub_message());					
						break;
				
					case(1) :
						int iHour = msg09.sotdma_state().sub_message() >> 9;
						if (iHour >= 24) {
							iHour = 24;
						} else {
							iHour = iHour + 9;
							if (iHour > 24) { iHour = iHour - 24;}
						}
						
						int iMinute = (msg09.sotdma_state().sub_message() >> 2) & 0x7F;
						if (iMinute > 60) { iMinute = 60; }
						
						subMsg = " "+
								 GmtUtils.fillString(3, String.valueOf(iHour), true) +
								 GmtUtils.fillString(2, String.valueOf(iMinute), true);
						break;
					
					case(2) : 
					case(4) :
					case(6) :
						if (msg09.sotdma_state().sub_message() > 2249) {
							subMsg = "     ";
						} else {
							subMsg = GmtUtils.fillString(5, String.valueOf(msg09.sotdma_state().sub_message()), true);
						}
						break;
					case(3) :
					case(5) :
					case(7) :
						if (msg09.sotdma_state().sub_message() > 16383) {
							subMsg = "     ";
						} else {
							subMsg = GmtUtils.fillString(5, String.valueOf(msg09.sotdma_state().sub_message()), true);
						}
						break;
					default : subMsg = "     ";
				}
				//communication state sub message 처리 종료
				
				slotInc      = "     ";
				numberOfSlot = " ";
				offset       = "     ";
				keepFlag     = " ";
				break;
				
			case(1) :	//ITDMA
				syncState = GmtUtils.fillString(1, String.valueOf(msg09.itdma_state().sync_state()), true);
				slotTimeOut = " ";
				subMsg = "     ";
				slotInc = GmtUtils.fillString(5, String.valueOf(msg09.itdma_state().slot_inc()), true);
				numberOfSlot = GmtUtils.fillString(1, String.valueOf(msg09.itdma_state().num_slots()), true);
				
				if (msg09.itdma_state().num_slots() >= 5 && msg09.itdma_state().num_slots() <= 7) {
					offset = String.valueOf(msg09.itdma_state().num_slots() + 8192);
				} else {
					offset = "     ";
				}
				
				keepFlag = GmtUtils.fillString(1, String.valueOf(msg09.itdma_state().keep_flag()), true); 
				break;
			}
			
			/*
			 * 	자선정보인지 확인하여 MessageType 결정
			 */
			if (aisDecoder.getTypeIEC() == IECType.VDO) 
				msgType = "05";
			else
				msgType = "15";
			
			StringBuilder sb = new StringBuilder();
			
			String header  = "";
			String data    = "";
			String extData = "";
			String packet  = "";
			
			/*
			 * 	STD 7.x. Extend 7.x 구성
			 */
			// 7.x Header 부 구성
			header = makeSTD7Header(String.valueOf(sensor.getCode()), "5", String.valueOf(msg09.userid()), msgDT, bsid, msgType);
			
			// Data 부 구성
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg09.altitiude()), true));
			sb.append(GmtUtils.fillString( 1, "1", true));
			sb.append(GmtUtils.fillString(10, String.valueOf(msg09.longitude()), true));
			sb.append(GmtUtils.fillString( 9, String.valueOf(msg09.latitude()), true));
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg09.sog()), true));
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg09.cog()), true));
			sb.append(GmtUtils.fillString( 2, "15", true));
			
			data = sb.toString();
			
			sb.setLength(0);
			sb.append(data);
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg09.comm_state()), true));
			sb.append(GmtUtils.fillString( 1, syncState, true));
			sb.append(GmtUtils.fillString( 1, slotTimeOut, true));
			sb.append(GmtUtils.fillString( 5, subMsg, true));
			sb.append(GmtUtils.fillString( 5, slotInc, true));
			sb.append(GmtUtils.fillString( 1, numberOfSlot, true));
			sb.append(GmtUtils.fillString( 5, offset, true));
			sb.append(GmtUtils.fillString( 1, keepFlag, true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg09.altitude_sensor()), true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg09.dte()), true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg09.assigned()), true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg09.raim()), true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg09.repeat()), true));
			sb.append(GmtUtils.fillString(14, s_bsUTC, true));
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg09.utc_sec()), true));
			sb.append(GmtUtils.fillString( 3, String.valueOf(msgDT.atZone(ZoneOffset.UTC).toInstant().toEpochMilli()), true));// Rcv Time ms
			
			extData = sb.toString();
			
			// 7.x, Extend 7.x 메시지 구성
		    // Header + Data Length + Data
			packet = makePacketwithCRC(header, data);
			if (!packet.isEmpty())
				std7Msg.setMessage1(packet);
			
			packet = makePacketwithCRC(header, extData);
			if (!packet.isEmpty())
				std7Msg.setExtendMsg1(packet);
			
			/*
			 *  STD 8.x 구성
			 */
			// 8.x Header부 구성
			header = makeSTD8Header(String.valueOf(sensor.getCode()), "5", String.valueOf(msg09.userid()), bsid, msgType, "13", msgDT);
			
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg09.assigned()), true));
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg09.altitiude()), true));
			sb.append(GmtUtils.fillString( 1, "0", true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg09.pos_acc()), true));
			sb.append(GmtUtils.fillString(10, String.valueOf(msg09.longitude()), true));
			sb.append(GmtUtils.fillString( 9, String.valueOf(msg09.latitude()), true));
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg09.sog()), true));
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg09.cog()), true));
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg09.comm_state()), true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg09.dte()), true));
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg09.utc_sec()), true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg09.raim()), true));
			
			data = sb.toString();
			
			// 8.x 메시지 구성
		    // Header + Data Length + Data
			packet = makePacketwithCRC(header, data);
			if (!packet.isEmpty())
				std8Msg.setMessage1(packet);
			
			result.setSuccess(true);
			
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorcode("Msg09 : "+ e.getMessage());
		}
		
		return result;
	}
	
	public GMTResult encodeMsg12(final AISDecoder aisDecoder, LocalDateTime msgDT, String bsid, SensorType sensor) {
		GMTResult result = new GMTResult();
		
		try
		{
			if (aisDecoder == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg12 : AIS Decoder is not assigned");
				return result;
			}
			
			Message12 msg12 = aisDecoder.getMsg12();
			if (msg12 == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg12 : AIS Message08 is not assigned");
				return result;
			}
			
			StringBuilder sb = new StringBuilder();
			String header = "";
			String data   = "";
			String packet = "";
			/*
			 * 	STD 7.x. Extend 7.x 구성
			 */
			// 7.x Header 부 구성
			header = makeSTD7Header("11", "7", String.valueOf(msg12.userid()), msgDT, bsid, "21");
			
			// Data 부 구성
			int len = msg12.message().trim().length();
			
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 2, " ", true));
			sb.append(GmtUtils.fillString( 1, "1", true));
			sb.append(GmtUtils.fillString( 1, "1", true));
			sb.append(GmtUtils.fillString(12, String.valueOf(msg12.userid()), true));
			sb.append(GmtUtils.fillString( 3, String.valueOf(len), true));
			sb.append(GmtUtils.fillString(len, msg12.message().trim(), true));
			
			data = sb.toString();
			
			// 7.x, Extend 7.x 메시지 구성
		    // Header + Data Length + Data
			packet = makePacketwithCRC(header, data);
			if (!packet.isEmpty())
			{
				std7Msg.setMessage1(packet);
				std7Msg.setExtendMsg1(packet);
			}

			result.setSuccess(true);
			
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorcode(" Msg12 : "+ e.getMessage());
		}
		
		return result;
	}
	
	public GMTResult encodeMsg13(final AISDecoder aisDecoder, LocalDateTime msgDT, String bsid, SensorType sensor) {
		GMTResult result = new GMTResult();
		
		try
		{
			if (aisDecoder == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg13 : AIS Decoder is not assigned");
				return result;
			}
			
			Message13 msg13 = aisDecoder.getMsg13();
			if (msg13 == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg13 : AIS Message08 is not assigned");
				return result;
			}
			
			StringBuilder sb = new StringBuilder();
			String header = "";
			String data   = "";
			String packet = "";
			
			/*
			 * 	STD 8.x 구성
			 */
			// 8.x Header부 구성
			header = makeSTD8Header(String.valueOf(sensor.getCode()), "7", String.valueOf(msg13.userid()), bsid, "52", "00", msgDT);
			
			// 8.x Data 부 구성
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 2, "13", true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg13.repeat()), true));
			sb.append(GmtUtils.fillString(12, String.valueOf(msg13.destid_1()), true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg13.sequence_1()), true));
			sb.append(GmtUtils.fillString(12, String.valueOf(msg13.destid_2()), true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg13.sequence_2()), true));
			sb.append(GmtUtils.fillString(12, String.valueOf(msg13.destid_3()), true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg13.sequence_3()), true));
			sb.append(GmtUtils.fillString(12, String.valueOf(msg13.destid_4()), true));
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg13.sequence_4()), true));
			
			data = sb.toString();
			
			// 8.x 메시지 구성
		    // Header + Data Length + Data
			packet = makePacketwithCRC(header, data);
			if(!packet.isEmpty()) {
				std8Msg.setMessage1(packet);
			}
			
			result.setSuccess(true);	
			
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorcode(" Msg13 : "+ e.getMessage());			
		}		
		
		return result;		
	}
	
		
	public GMTResult encodeMsg14(final AISDecoder aisDecoder, LocalDateTime msgDT, String bsid, SensorType sensor) 
	{
		GMTResult result = new GMTResult();
		
		try
		{
			if (aisDecoder == null)
			{
				result.setSuccess(false);
				result.setErrorcode("Msg14 : AIS Decoder is not assigned");
				return result;
			}
			
			Message14 msg14 = aisDecoder.getMsg14();
			if (msg14 == null)
			{
				result.setSuccess(false);
				result.setErrorcode("Msg14 : AIS Message08 is not assigned");
				return result;
			}
			
			StringBuilder sb = new StringBuilder();
			String header = "";
			String data   = "";
			String packet = "";
			
			/*
			 * 	STD 7.x 구성
			 */
			// 7.x Header부 구성
			header = makeSTD7Header(String.valueOf(sensor.getCode()), "7", String.valueOf(msg14.userid()), msgDT, bsid, "22");
			
			// 8.x Data 부 구성
			int len = msg14.message().trim().length();
			
			sb.setLength(0);
			sb.append(GmtUtils.fillString(  2, " ", true));
			sb.append(GmtUtils.fillString(  1, "1", true));
			sb.append(GmtUtils.fillString(  1, "1", true));			
			sb.append(GmtUtils.fillString( 12, String.valueOf(msg14.userid()), true));
			sb.append(GmtUtils.fillString(  3, String.valueOf(len), true));
			sb.append(GmtUtils.fillString(len, msg14.message().trim(), true));
						
			data = sb.toString();
			
			// 7.x 메시지 구성
		    // Header + Data Length + Data
			packet = makePacketwithCRC(header, data);
			if(!packet.isEmpty())
			{
				std7Msg.setMessage1(packet);
				std7Msg.setExtendMsg1(packet);
			}
			
			result.setSuccess(true);	
			
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorcode(" Msg14 : "+ e.getMessage());			
		}		
		
		return result;		
	}
	
	
	public GMTResult encodeMsg18(final AISDecoder aisDecoder, LocalDateTime msgDT, String bsid, LocalDateTime bsUTC, SensorType sensor)
	{
		GMTResult result = new GMTResult();
		
		try
		{
			if (aisDecoder == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg18 : AIS Decoder is not assigned");
				return result;
			}
			
			Message18 msg18 = aisDecoder.getMsg18();
			if (msg18 == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg18 : AIS Message08 is not assigned");
				return result;
			}
			
			
			LocalDateTime dtUTC;
			String s_bsUTC		= "";
			String syncState 	= "";
			String slotTimeOut 	= "";
			String subMsg 		= "";
			String offset 		= "";
			String slotInc 		= "";
			String numberOfSlot = "";
			String keepFlag 	= "";
			String msgType 		= "";
			
			if(bsUTC.isEqual(GmtUtils.defaultTime())) {
				s_bsUTC = GmtUtils.fillString(14, "", true);			
			} else {
				s_bsUTC = bsUTC.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
			}
			
			switch(msg18.comm_state()) {
			case(0) :	//SOTDMA
				syncState = GmtUtils.fillString(1, String.valueOf(msg18.sotdma_state().sync_state()), true);
				slotTimeOut = GmtUtils.fillString(1, String.valueOf(msg18.sotdma_state().slot_timeout()), true);
				
				//communication state sub message 처리
				switch(msg18.sotdma_state().slot_timeout()) {
					case(0) :
						subMsg = "     ";
						offset = String.valueOf(msg18.sotdma_state().sub_message());					
						break;
				
					case(1) :
						int iHour = msg18.sotdma_state().sub_message() >> 9;
						if (iHour >= 24) {
							iHour = 24;
						} else {
							iHour = iHour + 9;
							if (iHour > 24) { iHour = iHour - 24;}
						}
						
						int iMinute = (msg18.sotdma_state().sub_message() >> 2) & 0x7F;
						if (iMinute > 60) { iMinute = 60; }
						
						subMsg = " "+
								 GmtUtils.fillString(3, String.valueOf(iHour), true) +
								 GmtUtils.fillString(2, String.valueOf(iMinute), true);
						break;
					
					case(2) : 
					case(4) :
					case(6) :
						if (msg18.sotdma_state().sub_message() > 2249) {
							subMsg = "     ";
						} else {
							subMsg = GmtUtils.fillString(5, String.valueOf(msg18.sotdma_state().sub_message()), true);
						}
						break;
					case(3) :
					case(5) :
					case(7) :
						if (msg18.sotdma_state().sub_message() > 16383) {
							subMsg = "     ";
						} else {
							subMsg = GmtUtils.fillString(5, String.valueOf(msg18.sotdma_state().sub_message()), true);
						}
						break;
					default : subMsg = "     ";
				}
				//communication state sub message 처리 종료
				
				slotInc      = "     ";
				numberOfSlot = " ";
				offset       = "     ";
				keepFlag     = " ";
				break;
				
			case(1) :	//ITDMA
				syncState = GmtUtils.fillString(1, String.valueOf(msg18.itdma_state().sync_state()), true);
				slotTimeOut  = " ";
				subMsg       = "     ";
				slotInc      = GmtUtils.fillString(5, String.valueOf(msg18.itdma_state().slot_inc()), true);
				numberOfSlot = GmtUtils.fillString(1, String.valueOf(msg18.itdma_state().num_slots()), true);
				
				if (msg18.itdma_state().num_slots() >= 5 && msg18.itdma_state().num_slots() <= 7) {
					offset = String.valueOf(msg18.itdma_state().num_slots() + 8192);
				} else {
					offset = "     ";
				}
				
				keepFlag = GmtUtils.fillString(1, String.valueOf(msg18.itdma_state().keep_flag()), true); 
				break;
			}
			
			/*
			 * 	자선정보인지 확인하여 MessageType 결정
			 */
			if (aisDecoder.getTypeIEC() == IECType.VDO) 
				msgType = "01";
			else
				msgType = "11";
			
			StringBuilder sb = new StringBuilder();
			
			String header  = "";
			String data    = "";
			String extData = "";
			String packet  = "";
			
			/*
			 * 	STD 7.x. Extend 7.x 구성
			 */
			// 7.x Header 부 구성
			header = makeSTD7Header(String.valueOf(sensor.getCode()), "5", String.valueOf(msg18.userid()), msgDT, bsid, msgType);
			
			// Data 부 구성
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 1, "4", true));									// Mode
			sb.append(GmtUtils.fillString( 4, "0", true));			                        // ROT
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg18.sog()), true));          // SOG
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg18.pos_acc()), true));      // PosAcc
			sb.append(GmtUtils.fillString(10, String.valueOf(msg18.longitude()), true));    // Longitude
			sb.append(GmtUtils.fillString( 9, String.valueOf(msg18.latitude()), true));     // Latitude
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg18.cog()), true));          // COG
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg18.true_heading()), true)); // Heading
			
			data = sb.toString();
			
			sb.setLength(0);
			sb.append(data);
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg18.comm_state()), true));	// Communication state selector flag
			sb.append(GmtUtils.fillString( 1, syncState, true));                            // Sync state
			sb.append(GmtUtils.fillString( 1, slotTimeOut, true));                          // Slot timeout
			sb.append(GmtUtils.fillString( 5, subMsg, true));                               // sub message
			sb.append(GmtUtils.fillString( 5, slotInc, true));                              // Slot increment
			sb.append(GmtUtils.fillString( 1, numberOfSlot, true));                         // Number of Slot
			sb.append(GmtUtils.fillString( 5, offset, true));                               // Slot offset
			sb.append(GmtUtils.fillString( 1, keepFlag, true));                             // keep flag
			sb.append(GmtUtils.fillString( 2, "15", true));                                 // Navigation status
			sb.append(GmtUtils.fillString( 1, "0", true));			                        // Special manoeuve indicator
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg18.unit_flag()), true));    // Class B Unit flag
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg18.display_flag()), true)); // Class B Display flag
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg18.band_flag()), true));    // Class B Band flag
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg18.msg22_flag()), true));   // Class B Msg22 flag
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg18.dsc_flag()), true));     // Class B DSC flag
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg18.mode_flag()), true));    // Mode Flag
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg18.raim()), true));         // RAIM Flag
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg18.repeat()), true));       // Repeat indicator
			sb.append(GmtUtils.fillString(14, s_bsUTC, true));                              // Basestation UTC
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg18.utc_sec()), true));      // Time Stamp
			sb.append(GmtUtils.fillString( 3, String.valueOf(msgDT.atZone(ZoneOffset.UTC).toInstant().toEpochMilli()), true));// Rcv Time ms
			
			extData = sb.toString();
			
			// 7.x, Extend 7.x 메시지 구성
		    // Header + Data Length + Data
			packet = makePacketwithCRC(header, data);
			if (!packet.isEmpty())
				std7Msg.setMessage1(packet);
			
			packet = makePacketwithCRC(header, extData);
			if (!packet.isEmpty())
				std7Msg.setExtendMsg1(packet);
			
			/*
			 *  STD 8.x 구성
			 */
			// 8.x Header부 구성
			header = makeSTD8Header(String.valueOf(sensor.getCode()), "5", String.valueOf(msg18.userid()), bsid, msgType, "12", msgDT);
			
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 1, "0", true));
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg18.sog()), true));          // SOG
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg18.pos_acc()), true));      // PosAcc
			sb.append(GmtUtils.fillString(10, String.valueOf(msg18.longitude()), true));    // Longitude
			sb.append(GmtUtils.fillString( 9, String.valueOf(msg18.latitude()), true));     // Latitude
			sb.append(GmtUtils.fillString( 4, String.valueOf(msg18.cog()), true));          // COG
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg18.true_heading()), true)); // Heading
			sb.append(GmtUtils.fillString( 2, "15", true));                                 // Navigation status
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg18.unit_flag()), true));    // Class B Unit flag
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg18.display_flag()), true)); // Class B Display flag
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg18.band_flag()), true));    // Class B Band flag
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg18.msg22_flag()), true));   // Class B Msg22 flag
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg18.dsc_flag()), true));     // Class B DSC flag
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg18.utc_sec()), true));      // Time Stamp
			
			data = sb.toString();
			
			// 8.x 메시지 구성
		    // Header + Data Length + Data
			packet = makePacketwithCRC(header, data);
			if (!packet.isEmpty())
				std8Msg.setMessage1(packet);
			
			result.setSuccess(true);
			
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorcode("msg18 : "+ e.getMessage());
		}
		
		return result;
	}
	
	public GMTResult encodeMsg19(final AISDecoder aisDecoder, LocalDateTime msgDT, String bsid, LocalDateTime bsUTC, SensorType sensor)
	{
		GMTResult result = new GMTResult();
		try
		{
			if (aisDecoder == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg19 : AIS Decoder is not assigned");
				return result;
			}
			
			Message19 msg19 = aisDecoder.getMsg19();
			if (msg19 == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg19 : AIS Message19 is not assigned");
				return result;
			}
			
			GMTResult dynamicResult = makeMsg19Dynamic(aisDecoder, msgDT, bsid, bsUTC, sensor);
			GMTResult staticResult  = makeMsg19Static(aisDecoder, msgDT, bsid, sensor);
			
			if (dynamicResult.success && staticResult.success) {
				result.setSuccess(true);
				result.setErrorcode("");
			}
			
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorcode("Msg19 : "+ e.getMessage());
		}
		
		return result;		
	}
	
	public GMTResult encodeMsg21(final AISDecoder aisDecoder, LocalDateTime msgDT, String bsid, LocalDateTime bsUTC, SensorType sensor)
	{
		GMTResult result = new GMTResult();
		
		try
		{
			if (aisDecoder == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg21 : AIS Decoder is not assigned");
				return result;
			}
			
			Message21 msg21 = aisDecoder.getMsg21();
			if (msg21 == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg21 : AIS Message08 is not assigned");
				return result;
			}
			
			
			LocalDateTime dtUTC;
			String s_bsUTC	= "";
			String msgType 	= "";			
			String header 	= "";
			String data   	= "";
			String extData  = "";
			String shipName = "";
			String packet   = "";
			
			StringBuilder sb = new StringBuilder();
						
			if(bsUTC.isEqual(GmtUtils.defaultTime())) {
				s_bsUTC = GmtUtils.fillString(14, "", true);			
			} else {
				s_bsUTC = bsUTC.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
			}
			
			/*
			 * 	자선정보인지 확인하여 MessageType 결정
			 */
			if (aisDecoder.getTypeIEC() == IECType.VDO) 
				msgType = "09";
			else
				msgType = "19";
			
			
			shipName = msg21.name().trim().replace("*", " ");
			/*
			 * 	STD 7.x. Extend 7.x 구성
			 */
			// 7.x Header 부 구성
			header = makeSTD7Header(String.valueOf(sensor.getCode()), "5", String.valueOf(msg21.userid()), msgDT, bsid, msgType);
			
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 1, "0", true));									// Mode															
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg21.aton_type()), true));    // Type of AtoN
			sb.append(GmtUtils.fillString(34, shipName, true));                             // AToN Name
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg21.pos_acc()), true));      // PosAcc
			sb.append(GmtUtils.fillString(10, String.valueOf(msg21.longitude()), true));    // Longitude
			sb.append(GmtUtils.fillString( 9, String.valueOf(msg21.latitude()), true));     // Latitude
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg21.dim_bow()), true));      // Dimension A
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg21.dim_stern()), true));    // Dimension B
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg21.dim_port()), true));     // Dimension C
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg21.dim_starboard()), true));// Dimension D
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg21.pos_type()), true));     // Pos Type
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg21.off_position()), true)); // Off Pos
			sb.append(GmtUtils.fillString( 3, " ", true));                                  // Reserved
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg21.raim()), true));         // RAIM Flag
			
			data = sb.toString();
			
			sb.setLength(0);
			sb.append(data);
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg21.status()), true));	// AToN Status
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg21.virtual()), true));  // Virtual AToN Flag
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg21.repeat()), true));   // repeat indicator
			sb.append(GmtUtils.fillString(14, s_bsUTC, true));                          // Basestation UTC
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg21.utc_sec()), true));  // Time Stamp
			sb.append(GmtUtils.fillString( 3, String.valueOf(msgDT.atZone(ZoneOffset.UTC).toInstant().toEpochMilli()), true));// Rcv Time ms
			
			extData = sb.toString();
			
			// 7.x, Extend 7.x 메시지 구성
		    // Header + Data Length + Data
			packet = makePacketwithCRC(header, data);
			if (!packet.isEmpty()) {
				std7Msg.setMessage1(packet);				
			}
			
			packet = makePacketwithCRC(header, extData);
			if (!packet.isEmpty()) {
				std7Msg.setExtendMsg1(packet);
			}
			
			
			/*
			 * 	STD 8.x. Extend
			 */
			// 8.x Header 부 구성
			header = makeSTD8Header(String.valueOf(sensor.getCode()), "5", String.valueOf(msg21.userid()), bsid, msgType, "14", msgDT);
			
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 1, "0", true));									// Mode															
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg21.aton_type()), true));    // Type of AtoN
			sb.append(GmtUtils.fillString(34, shipName, true));                             // AToN Name
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg21.pos_acc()), true));      // PosAcc
			sb.append(GmtUtils.fillString(10, String.valueOf(msg21.longitude()), true));    // Longitude
			sb.append(GmtUtils.fillString( 9, String.valueOf(msg21.latitude()), true));     // Latitude
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg21.dim_bow()), true));      // Dimension A
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg21.dim_stern()), true));    // Dimension B
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg21.dim_port()), true));     // Dimension C
			sb.append(GmtUtils.fillString( 3, String.valueOf(msg21.dim_starboard()), true));// Dimension D
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg21.pos_type()), true));     // Pos Type
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg21.off_position()), true)); // Off Pos
			sb.append(GmtUtils.fillString( 3, " ", true));                                  // Reserved
			sb.append(GmtUtils.fillString( 1, String.valueOf(msg21.raim()), true));         // RAIM Flag
			
			data = sb.toString();
			
			// 8.x 메시지 구성
		    // Header + Data Length + Data
			packet = makePacketwithCRC(header, data);
			if (!packet.isEmpty()) {
				std8Msg.setMessage1(packet);				
			}
			
			result.setSuccess(true);
			
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorcode("Msg21 : "+ e.getMessage());
		}
		
		return result;
	}
	
	public GMTResult encodeMsg24(final AISDecoder aisDecoder, LocalDateTime msgDT, String bsid, SensorType sensor) {
		GMTResult result = new GMTResult();
		try
		{
			if (aisDecoder == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg24 : AIS Decoder is not assigned");
				return result;
			}
			
			Message24 msg24 = aisDecoder.getMsg24();
			if (msg24 == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg24 : AIS Message24 is not assigned");
				return result;
			}
			
			String msgType  = "";
			String s_name   = "";
			String s_Vender = "";
			
			//자선 정보인지 확인하여 MessageType 결정
			if (aisDecoder.getTypeIEC() == IECType.VDO) {
				msgType = "02";
			} else {
				msgType = "12";
			}
			
			StringBuilder sb = new StringBuilder();
			
			String header  = "";
			String data    = "";
			String packet  = "";	
			
			/*
			 * STD 7.x, Extend 7.x 구성
			 */
			
			//7.x Header 부 구성
			
			header = makeSTD7Header(String.valueOf(sensor.getCode()), "6", String.valueOf(msg24.userid()), msgDT, bsid, msgType);
			
			s_name = msg24.name().trim();
			s_name = s_name.replace("*", " ");
			
			s_Vender = msg24.vendor_id().trim();
			s_Vender = s_Vender.replace("*", " ");
			
			//Data 부 구성
			//A
			if (msg24.part_number() == 0) {
				sb.setLength(0);
				sb.append(GmtUtils.fillString( 9,    " ", true));
				sb.append(GmtUtils.fillString(30, s_name, true));
				sb.append(GmtUtils.fillString( 7,    " ", true));
				sb.append(GmtUtils.fillString( 4,    "0", true));
				sb.append(GmtUtils.fillString( 3,    "0", true));
				sb.append(GmtUtils.fillString( 3,    "0", true));
				sb.append(GmtUtils.fillString( 3,    "0", true));
				sb.append(GmtUtils.fillString( 3,    "0", true));
				sb.append(GmtUtils.fillString( 4,    "0", true));
				sb.append(GmtUtils.fillString( 2, String.valueOf(msg24.pos_type()), true));
				sb.append(GmtUtils.fillString( 8, "00002460", true));
				sb.append(GmtUtils.fillString(20,    " ", true));
				sb.append("1");
				sb.append("0");
				sb.append(GmtUtils.fillString( 1, String.valueOf(msg24.part_number()), true));
				sb.append(GmtUtils.fillString( 7,    " ", true));
				sb.append(GmtUtils.fillString( 1, String.valueOf(msg24.repeat()), true));
				sb.append("9");
			}
			//B
			else if (msg24.part_number() == 1) {
				sb.setLength(0);
				sb.append(GmtUtils.fillString( 9,    " ", true));
				sb.append(GmtUtils.fillString(30,    " ", true));
				
				if (msg24.callsign() == "0000000") {
					sb.append(GmtUtils.fillString( 7,    " ", true));
				}else {
					sb.append(GmtUtils.fillString( 7, msg24.callsign(), true));
				}
				sb.append(GmtUtils.fillString( 4,    String.valueOf(msg24.ship_type()), true));
				sb.append(GmtUtils.fillString( 3,    String.valueOf(msg24.dim_bow()), true));
				sb.append(GmtUtils.fillString( 3,    String.valueOf(msg24.dim_stern()), true));
				sb.append(GmtUtils.fillString( 3,    String.valueOf(msg24.dim_port()), true));
				sb.append(GmtUtils.fillString( 3,    String.valueOf(msg24.dim_starboard()), true));
				sb.append(GmtUtils.fillString( 4,    "0", true));
				sb.append(GmtUtils.fillString( 2, String.valueOf(msg24.pos_type()), true)); 
				sb.append(GmtUtils.fillString( 8, "00002460", true));
				sb.append(GmtUtils.fillString(20,    " ", true));
				sb.append("1");
				sb.append("0");
				sb.append(GmtUtils.fillString( 1, String.valueOf(msg24.part_number()), true));
				sb.append(GmtUtils.fillString( 7,    s_Vender, true));
				sb.append(GmtUtils.fillString( 1, String.valueOf(msg24.repeat()), true));
				sb.append("9");
			}
			
			data = sb.toString();
			
			// 7.x, Extend 7.x 메시지 구성
			// Header + Data  Length + Data
			packet = makePacketwithCRC(header, data);
			if (!packet.isEmpty()) {
				std7Msg.setMessage1(packet);
				std7Msg.setExtendMsg1(packet);
			}
			
			//STD 8.x 구성
			// 8.x Header 부 구성
			header = makeSTD8Header(String.valueOf(sensor.getCode()), "6", String.valueOf(msg24.userid()), bsid, msgType,"12",msgDT);
			
			// 8.x Data 부 구성
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 9,    " ", true));
			sb.append(GmtUtils.fillString(30,    " ", true));
			
			if (msg24.callsign() == "0000000") {
				sb.append(GmtUtils.fillString( 7,    " ", true));
			}else {
				sb.append(GmtUtils.fillString( 7, msg24.callsign(), true));
			}
			sb.append(GmtUtils.fillString( 4,    String.valueOf(msg24.ship_type()), true));
			sb.append(GmtUtils.fillString( 3,    String.valueOf(msg24.dim_bow()), true));
			sb.append(GmtUtils.fillString( 3,    String.valueOf(msg24.dim_stern()), true));
			sb.append(GmtUtils.fillString( 3,    String.valueOf(msg24.dim_port()), true));
			sb.append(GmtUtils.fillString( 3,    String.valueOf(msg24.dim_starboard()), true));
			sb.append(GmtUtils.fillString( 4,    "0", true)); 
			sb.append(GmtUtils.fillString(20,    " ", true)); 
			sb.append(GmtUtils.fillString( 8, "00002460", true));
			sb.append(GmtUtils.fillString( 2, String.valueOf(msg24.pos_type()), true));
			sb.append("9");
			sb.append("1");
			
			data = sb.toString();
			
			//8.x 메시지 구성
			//Header + Data Length + Data
			packet = makePacketwithCRC(header, data);
			if (!packet.isEmpty())
				std8Msg.setMessage1(packet);
			
			result.setSuccess(true);
			
		} catch(Exception e) {
			result.setSuccess(false);
			result.setErrorcode("Msg24 : " + e.getMessage());
		}
		
		return result;
	}
	
	public GMTResult encodeMsg27(final AISDecoder aisDecoder, LocalDateTime msgDT, String bsid, LocalDateTime bsUTC, SensorType sensor) {
		GMTResult result = new GMTResult();
		
		try
		{
			if (aisDecoder == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg27 : AIS Decoder is not assigned");
				return result;
			}
			
			Message27 msg27 = aisDecoder.getMsg27();
			if (msg27 == null) {
				result.setSuccess(false);
				result.setErrorcode("Msg27 : AIS Message27 is not assigned");
				return result;
			}
			
			LocalDateTime dtUTC;
			String s_bsUTC = "";
			
			if(bsUTC.isEqual(GmtUtils.defaultTime())) {
				s_bsUTC = GmtUtils.fillString(14, "", true);			
			} else {
				s_bsUTC = bsUTC.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
			}
			
			StringBuilder sb = new StringBuilder();
			
			String header  = "";
			String data    = "";
			String extData = "";
			String packet  = "";
			
			/*
			 *  STD 7.x, Extend 7.x 구성
			 */
			// 7.x Header 부 구성
			header = makeSTD7Header(String.valueOf(sensor.getCode()), "5", String.valueOf(msg27.userid()), msgDT, bsid, "14");
			
			// 7.x Data 부 구성
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 1, 									   "0", true)); //Mode
			sb.append(GmtUtils.fillString( 4, 									   "0", true)); //Rot
			sb.append(GmtUtils.fillString( 4, 			   String.valueOf(msg27.sog()), true)); //SOG
			sb.append(GmtUtils.fillString( 1,  		   String.valueOf(msg27.pos_acc()), true)); //PosAcc
			sb.append(GmtUtils.fillString(10, String.valueOf(msg27.longitude() * 1000), true)); //Longitude
			sb.append(GmtUtils.fillString( 9,  String.valueOf(msg27.latitude() * 1000), true)); //Latitude
			sb.append(GmtUtils.fillString( 4, 			   String.valueOf(msg27.cog()), true)); //COG
			sb.append(GmtUtils.fillString( 3, 							         "511", true)); //Heading
			
			data = sb.toString();
			
			// Extend 7.x 확장 Data 부 구성
			
			sb.setLength(0);
			sb.append(data);
			sb.append(GmtUtils.fillString( 1, 									   "0", true)); //Communication state Selector
			sb.append(GmtUtils.fillString( 1, 									   " ", true)); //Sync state
			sb.append(GmtUtils.fillString( 1, 									   " ", true)); //Slot timeout
			sb.append(GmtUtils.fillString( 5, 									   " ", true)); //sub message
			sb.append(GmtUtils.fillString( 5, 									   " ", true)); //Slot increment
			sb.append(GmtUtils.fillString( 1, 									   " ", true)); //Number of Slot
			sb.append(GmtUtils.fillString( 5, 									   " ", true)); //Slot offset
			sb.append(GmtUtils.fillString( 1, 									   " ", true)); //Keep Flag
			sb.append(GmtUtils.fillString( 2, 		String.valueOf(msg27.nav_status()), true)); //Navigation Status
			sb.append(GmtUtils.fillString( 1, 									   "0", true)); //Special manoeuvre indicator
			sb.append(GmtUtils.fillString( 1, 									   " ", true)); //Class B Unit Falg
			sb.append(GmtUtils.fillString( 1, 									   " ", true)); //Class B Display Falg
			sb.append(GmtUtils.fillString( 1, 									   " ", true)); //Class B Band Falg
			sb.append(GmtUtils.fillString( 1, 									   " ", true)); //Class B Msg22 Falg
			sb.append(GmtUtils.fillString( 1, 									   " ", true)); //Class B DSC Falg
			sb.append(GmtUtils.fillString( 1, 									   " ", true)); //Mode Flag
			sb.append(GmtUtils.fillString( 1, 			  String.valueOf(msg27.raim()), true)); //Raim Flag 
			sb.append(GmtUtils.fillString( 1, 			String.valueOf(msg27.repeat()), true)); //Repeat indicator
			sb.append(GmtUtils.fillString(14, 								   s_bsUTC, true)); //BaseStation UTC
			sb.append(GmtUtils.fillString( 2, 								      "60", true)); //time Stamp
			sb.append(GmtUtils.fillString( 3, String.valueOf(msgDT.atZone(ZoneOffset.UTC).toInstant().toEpochMilli()), true));// Rcv Time ms
			
			extData = sb.toString();
			
			// 7.x, Extend 7.x 메시지 구성
			// Header + Data Length + Data
			packet = makePacketwithCRC(header, data);
			if (!packet.isEmpty())
				std7Msg.setMessage1(packet);
			
			packet = makePacketwithCRC(header, extData);
			if (!packet.isEmpty())
				std7Msg.setExtendMsg1(packet);
			
			/*
			 *  STD 8.x 구성
			 */
			//8.x header 부 구성
			header = makeSTD8Header(String.valueOf(sensor.getCode()), "5", String.valueOf(msg27.userid()), bsid, "11","14",msgDT);
			
			//8.x data 부 구성
			
			sb.setLength(0);
			sb.append(GmtUtils.fillString( 1, 									   "0", true)); //Mode
			sb.append(GmtUtils.fillString( 4, 									   "0", true)); //Rot
			sb.append(GmtUtils.fillString( 4, 			   String.valueOf(msg27.sog()), true)); //SOG
			sb.append(GmtUtils.fillString( 1,  		   String.valueOf(msg27.pos_acc()), true)); //PosAcc
			sb.append(GmtUtils.fillString(10, String.valueOf(msg27.longitude() * 1000), true)); //Longitude
			sb.append(GmtUtils.fillString( 9,  String.valueOf(msg27.latitude() * 1000), true)); //Latitude
			sb.append(GmtUtils.fillString( 4, 			   String.valueOf(msg27.cog()), true)); //COG
			sb.append(GmtUtils.fillString( 3, 							         "511", true)); //Heading
			sb.append(GmtUtils.fillString( 3, 		String.valueOf(msg27.nav_status()), true));
			sb.append(GmtUtils.fillString( 2, 									   " ", true));		
			
			data = sb.toString();
			
			// 8.x 메시지 구성
		    // Header + Data Length + Data
			packet = makePacketwithCRC(header, data);
			if (!packet.isEmpty())
				std8Msg.setMessage1(packet);
			
			result.setSuccess(true);
			
		}catch(Exception e) {
			result.setSuccess(false);
			result.setErrorcode("Msg27 : " + e.getMessage());
		}
		
		return result;
	}

}
