private void ParsePacket(IPacket pk) { switch ((Cmd)pk.Cmd) { case Cmd.A_DotData: { long time = pk.GetByteToInt(); int x = pk.GetShort(); int y = pk.GetShort(); int fx = pk.GetByteToInt(); int fy = pk.GetByteToInt(); int force = pk.GetByteToInt(); long timeLong = mPrevDotTime + time; Dot.Builder builder = new Dot.Builder(MaxForce); builder.owner(mOwnerId) .section(mSectionId) .note(mNoteId) .page(mPageId) .timestamp(timeLong) .coord(x, fx, y, fy) .force(force) .color(mCurrentColor); if (!IsStartWithDown) { if (!IsStartWithPaperInfo) { //펜 다운 없이 페이퍼 정보 없고 무브가 오는 현상(다운 - 무브 - 업 - 다운X - 무브) Callback.onErrorDetected(this, ErrorType.MissingPenDown, -1, null, null); } else { //펜 다운 없이 페이퍼 정보 있고 무브가 오는 현상(다운 - 무브 - 업 - 다운X - 무브) builder.dotType(DotTypes.PEN_ERROR); var errorDot = builder.Build(); Callback.onErrorDetected(this, ErrorType.MissingPenDown, -1, errorDot, null); IsStartWithDown = true; builder.timestamp(Time.GetUtcTimeStamp()); } } if (!IsStartWithDown) { if (!IsStartWithPaperInfo) { //펜 다운 없이 페이퍼 정보 없고 무브가 오는 현상(다운 - 무브 - 업 - 다운X - 무브) Callback.onErrorDetected(this, ErrorType.MissingPenDown, -1, null, null); } else { timeLong = Time.GetUtcTimeStamp(); PenDownTime = timeLong; //펜 다운 없이 페이퍼 정보 있고 무브가 오는 현상(다운 - 무브 - 업 - 다운X - 무브) builder.dotType(DotTypes.PEN_ERROR); var errorDot = builder.Build(); Callback.onErrorDetected(this, ErrorType.MissingPenDown, PenDownTime, errorDot, null); IsStartWithDown = true; builder.timestamp(timeLong); } } if (timeLong < 10000) { // 타임스템프가 10000보다 작을 경우 도트 필터링 builder.dotType(DotTypes.PEN_ERROR); var errorDot = builder.Build(); Callback.onErrorDetected(this, ErrorType.InvalidTime, PenDownTime, errorDot, null); } Dot dot = null; if (IsStartWithDown && IsStartWithPaperInfo && IsBeforePaperInfo) { // 펜다운의 경우 시작 도트로 저장 dot = builder.timestamp(PenDownTime).dotType(DotTypes.PEN_DOWN).Build(); } else if (IsStartWithDown && IsStartWithPaperInfo && !IsBeforePaperInfo && IsBeforeMiddle) { // 펜다운이 아닌 경우 미들 도트로 저장 dot = builder.dotType(DotTypes.PEN_MOVE).Build(); } else if (IsStartWithDown && !IsStartWithPaperInfo) { //펜 다운 이후 페이지 체인지 없이 도트가 들어왔을 경우 Callback.onErrorDetected(this, ErrorType.MissingPageChange, PenDownTime, null, null); } if (dot != null) { ProcessDot(dot); } mPrevDot = dot; mPrevDotTime = timeLong; IsBeforeMiddle = true; IsBeforePaperInfo = false; } break; case Cmd.A_DotUpDownDataNew: case Cmd.A_DotUpDownData: { long updownTime = pk.GetLong(); int updown = pk.GetByteToInt(); byte[] cbyte = pk.GetBytes(3); mCurrentColor = ByteConverter.ByteToInt(new byte[] { cbyte[2], cbyte[1], cbyte[0], (byte)0xFF }); if (updown == 0x00) { // 펜 다운 일 경우 Start Dot의 timestamp 설정 mPrevDotTime = updownTime; //IsPrevDotDown = true; if (IsBeforeMiddle && mPrevDot != null) { // 펜업이 넘어오지 않는 경우 //var errorDot = mPrevDot.Clone(); //errorDot.DotType = DotTypes.PEN_ERROR; //Callback.onErrorDetected(this, ErrorType.MissingPenUp, PenDownTime, errorDot, null); MakeUpDot(); } IsStartWithDown = true; PenDownTime = updownTime; //Callback.onUpDown( this, false ); } else if (updown == 0x01) { mPrevDotTime = -1; if (IsStartWithDown && IsBeforeMiddle && mPrevDot != null) { MakeUpDot(false); } else if (!IsStartWithDown && !IsBeforeMiddle) { Callback.onErrorDetected(this, ErrorType.MissingPenDownPenMove, PenDownTime, null, null); } else if (!IsBeforeMiddle) { // 무브없이 다운-업만 들어올 경우 UP dot을 보내지 않음 Callback.onErrorDetected(this, ErrorType.MissingPenMove, PenDownTime, null, null); } IsStartWithDown = false; PenDownTime = -1; } IsBeforeMiddle = false; IsStartWithPaperInfo = false; mPrevDot = null; } break; case Cmd.A_DotIDChange: if (IsStartWithDown && IsBeforeMiddle && mPrevDot != null) { MakeUpDot(false); } byte[] rb = pk.GetBytes(4); mSectionId = (int)(rb[3] & 0xFF); mOwnerId = ByteConverter.ByteToInt(new byte[] { rb[0], rb[1], rb[2], (byte)0x00 }); mNoteId = pk.GetInt(); mPageId = pk.GetInt(); //IsPrevDotDown = true; IsBeforePaperInfo = true; IsStartWithPaperInfo = true; break; case Cmd.A_PenOnState: pk.Move(8); int STATUS = pk.GetByteToInt(); int FORCE_MAX = pk.GetByteToInt(); MaxForce = (short)FORCE_MAX; string SW_VER = pk.GetString(5); if (STATUS == 0x00) { SendPenOnOffData(); Clean(); } else if (STATUS == 0x01) { Reset(); SendPenOnOffData(); SendRTCData(); needToInputDefaultPassword = true; mOfflineworker.PenMaxForce = FORCE_MAX; Callback.onConnected(this, FORCE_MAX, SW_VER); } break; case Cmd.A_RTCsetResponse: break; case Cmd.A_PenStatusResponse: if (!Authenticated) { Authenticated = true; needToInputDefaultPassword = false; Callback.onPenAuthenticated(this); } pk.Move(2); int stat_timezone = pk.GetInt(); long stat_timetick = pk.GetLong(); int stat_forcemax = pk.GetByteToInt(); int stat_battery = pk.GetByteToInt(); int stat_usedmem = pk.GetByteToInt(); int stat_pencolor = pk.GetInt(); bool stat_autopower = pk.GetByteToInt() == 2 ? false : true; bool stat_accel = pk.GetByteToInt() == 2 ? false : true; bool stat_hovermode = pk.GetByteToInt() == 2 ? false : true; bool stat_beep = pk.GetByteToInt() == 2 ? false : true; short stat_autoshutdowntime = pk.GetShort(); short stat_pensensitivity = pk.GetShort(); string model_name = string.Empty; if (pk.CheckMoreData()) { int model_name_length = pk.GetByte(); model_name = pk.GetString(model_name_length); } Callback.onReceivedPenStatus(this, stat_timezone, stat_timetick, stat_forcemax, stat_battery, stat_usedmem, stat_pencolor, stat_autopower, stat_accel, stat_hovermode, stat_beep, stat_autoshutdowntime, stat_pensensitivity, model_name); break; // 오프라인 데이터 크기,갯수 전송 case Cmd.A_OfflineDataInfo: mOfflineTotalFileCount = pk.GetInt(); mOfflineTotalDataSize = pk.GetInt(); System.Console.WriteLine("[PenCommCore] A_OfflineDataInfo : {0}, {1}", mOfflineTotalFileCount, mOfflineTotalDataSize); Callback.onStartOfflineDownload(this); IsStartOfflineTask = true; break; // 오프라인 전송 최종 결과 응답 case Cmd.A_OfflineResultResponse: int result = pk.GetByteToInt(); //System.Console.WriteLine( "[PenCommCore] A_OfflineDataResponse : {0}", result ); IsStartOfflineTask = false; Callback.onFinishedOfflineDownload(this, result == 0x00 ? false : true); mOfflineworker.onFinishDownload(); mOfflineRcvDataSize = 0; break; // 오프라인 파일 정보 case Cmd.A_OfflineFileInfo: mOfflineFileName = pk.GetString(128); mOfflineFileSize = pk.GetInt(); mOfflinePacketCount = pk.GetShort(); mOfflinePacketSize = pk.GetShort(); System.Console.WriteLine("[PenCommCore] offline file transfer is started ( name : " + mOfflineFileName + ", size : " + mOfflineFileSize + ", packet_qty : " + mOfflinePacketCount + ", packet_size : " + mOfflinePacketSize + " )"); mOfflineDataBuilder = null; mOfflineDataBuilder = new OfflineDataSerializer(mOfflineFileName, mOfflinePacketCount, mOfflineFileName.Contains(".zip") ? true : false); SendOfflineInfoResponse(); break; // 오프라인 파일 조각 전송 case Cmd.A_OfflineChunk: int index = pk.GetShort(); // 체크섬 필드 byte cs = pk.GetByte(); // 체크섬 계산 byte calcChecksum = pk.GetChecksum(); // 오프라인 데이터 byte[] data = pk.GetBytes(); // 체크섬이 틀리거나, 카운트, 사이즈 정보가 맞지 않으면 버린다. if (cs == calcChecksum && mOfflinePacketCount > index && mOfflinePacketSize >= data.Length) { mOfflineDataBuilder.Put(data, index); // 만약 Chunk를 다 받았다면 offline data를 처리한다. if (mOfflinePacketCount == mOfflineDataBuilder.chunks.Count) { string output = mOfflineDataBuilder.MakeFile(); if (output != null) { SendOfflineChunkResponse((short)index); mOfflineworker.onCreateFile(mOfflineDataBuilder.sectionId, mOfflineDataBuilder.ownerId, mOfflineDataBuilder.noteId, output); } mOfflineDataBuilder = null; } else { SendOfflineChunkResponse((short)index); } mOfflineRcvDataSize += data.Length; if (mOfflineTotalDataSize > 0) { System.Console.WriteLine("[PenCommCore] mOfflineRcvDataSize : " + mOfflineRcvDataSize); Callback.onUpdateOfflineDownload(this, mOfflineTotalDataSize, mOfflineRcvDataSize); } } else { System.Console.WriteLine("[PenCommCore] offline data file verification failed ( index : " + index + " )"); } break; case Cmd.A_UsingNoteNotifyResponse: { bool accepted = pk.GetByteToInt() == 0x01; Callback.onAvailableNoteAccepted(this, accepted); } break; case Cmd.A_OfflineNoteListResponse: { int status = pk.GetByteToInt(); byte[] rxb = pk.GetBytes(4); int section = (int)(rxb[3] & 0xFF); int owner = ByteConverter.ByteToInt(new byte[] { rxb[0], rxb[1], rxb[2], (byte)0x00 }); int noteCnt = pk.GetByteToInt(); for (int i = 0; i < noteCnt; i++) { int note = pk.GetInt(); mOfflineNotes.Add(new OfflineDataInfo(section, owner, note)); } if (status == 0x01) { OfflineDataInfo[] array = mOfflineNotes.ToArray(); Callback.onOfflineDataList(this, array); mOfflineNotes.Clear(); } else { Callback.onOfflineDataList(this, new OfflineDataInfo[0]); } } break; case Cmd.A_OfflineDataRemoveResponse: //System.Console.WriteLine( "[PenCommCore] CMD.A_OfflineDataRemoveResponse" ); break; case Cmd.A_PasswordRequest: { int countRetry = pk.GetByteToInt(); int countReset = pk.GetByteToInt(); System.Console.WriteLine("[PenCommCore] A_PasswordRequest ( " + countRetry + " / " + countReset + " )"); if (needToInputDefaultPassword) { _ReqInputPassword(DEFAULT_PASSWORD); needToInputDefaultPassword = false; } else { Callback.onPenPasswordRequest(this, countRetry, countReset); } } break; case Cmd.A_PasswordSetResponse: { int setResult = pk.GetByteToInt(); //System.Console.WriteLine( "[PenCommCore] A_PasswordSetResponse => " + setResult ); if (setResult == 0x00) { needToInputDefaultPassword = true; } Callback.onPenPasswordSetUpResponse(this, setResult == 0x00 ? true : false); } break; case Cmd.A_PenSensitivityResponse: case Cmd.A_AutoShutdownTimeResponse: case Cmd.A_AutoPowerOnResponse: case Cmd.A_BeepSetResponse: case Cmd.A_PenColorSetResponse: case Cmd.A_HoverOnOffResponse: ResPenSetup((Cmd)pk.Cmd, pk.GetByteToInt() == 0x01); break; case Cmd.A_PenSWUpgradeRequest: short idx = pk.GetShort(); ResponseChunkRequest(idx); break; case Cmd.A_PenSWUpgradeStatus: { int upgStatus = pk.GetByteToInt(); if (upgStatus == 0x02) { return; } Callback.onReceivedFirmwareUpdateResult(this, upgStatus == 0x01); mFwChunk = null; } break; } }
public void ParsePacket(Packet packet) { //Debug.WriteLine("[PenCommCore] ParsePacket : " + packet.Cmd); switch ((Cmd)packet.Cmd) { case Cmd.A_DotData: { long time = packet.GetByteToInt(); int x = packet.GetShort(); int y = packet.GetShort(); int fx = packet.GetByteToInt(); int fy = packet.GetByteToInt(); int force = packet.GetByteToInt(); long timeLong = mPrevDotTime + time; if (!IsStartWithDown || timeLong < 10000) { Debug.WriteLine("[PenCommCore] this stroke start with middle dot."); return; } if (IsPrevDotDown) { // 펜업의 경우 시작 도트로 저장 IsPrevDotDown = false; ProcessDot(mOwnerId, mSectionId, mNoteId, mPageId, timeLong, x, y, fx, fy, force, DotTypes.PEN_DOWN, mCurrentColor); } else { // 펜업이 아닌 경우 미들 도트로 저장 ProcessDot(mOwnerId, mSectionId, mNoteId, mPageId, timeLong, x, y, fx, fy, force, DotTypes.PEN_MOVE, mCurrentColor); } mPrevDotTime = timeLong; mPrevPacket = packet; } break; case Cmd.A_DotUpDownDataNew: case Cmd.A_DotUpDownData: { // TODO Check long updownTime = packet.GetLong(); int updown = packet.GetByteToInt(); byte[] cbyte = packet.GetBytes(3); mCurrentColor = ByteConverter.ByteToInt(new byte[] { cbyte[2], cbyte[1], cbyte[0], (byte)0 }); if (updown == 0x00) { // 펜 다운 일 경우 Start Dot의 timestamp 설정 mPrevDotTime = updownTime; IsPrevDotDown = true; IsStartWithDown = true; //Callback.onUpDown(this, false); } else if (updown == 0x01) { if (mPrevPacket != null) { mPrevPacket.Reset(); // 펜 업 일 경우 바로 이전 도트를 End Dot로 삽입 int time = mPrevPacket.GetByteToInt(); int x = mPrevPacket.GetShort(); int y = mPrevPacket.GetShort(); int fx = mPrevPacket.GetByteToInt(); int fy = mPrevPacket.GetByteToInt(); int force = mPrevPacket.GetByteToInt(); ProcessDot(mOwnerId, mSectionId, mNoteId, mPageId, updownTime, x, y, fx, fy, force, DotTypes.PEN_UP, mCurrentColor); } //Callback.onUpDown(this, true); IsStartWithDown = false; } mPrevPacket = null; } break; case Cmd.A_DotIDChange: byte[] rb = packet.GetBytes(4); mSectionId = (int)(rb[3] & 0xFF); mOwnerId = ByteConverter.ByteToInt(new byte[] { rb[0], rb[1], rb[2], (byte)0x00 }); mNoteId = packet.GetInt(); mPageId = packet.GetInt(); break; case Cmd.A_PenOnState: packet.Move(8); int STATUS = packet.GetByteToInt(); int FORCE_MAX = packet.GetByteToInt(); string SW_VER = packet.GetString(5); if (STATUS == 0x00) { SendPenOnOffData(); } else if (STATUS == 0x01) { Reset(); SendPenOnOffData(); SendRTCData(); PenController.onConnected(new ConnectedEventArgs(SW_VER, FORCE_MAX)); PenMaxForce = FORCE_MAX; mOfflineworker.PenMaxForce = FORCE_MAX; } break; case Cmd.A_RTCsetResponse: break; case Cmd.A_PenStatusResponse: if (!Authenticated) { Authenticated = true; PenController.onPenAuthenticated(); } packet.Move(2); int stat_timezone = packet.GetInt(); long stat_timetick = packet.GetLong(); int stat_forcemax = packet.GetByteToInt(); int stat_battery = packet.GetByteToInt(); int stat_usedmem = packet.GetByteToInt(); int stat_pencolor = packet.GetInt(); bool stat_autopower = packet.GetByteToInt() == 2 ? false : true; bool stat_accel = packet.GetByteToInt() == 2 ? false : true; bool stat_hovermode = packet.GetByteToInt() == 2 ? false : true; bool stat_beep = packet.GetByteToInt() == 2 ? false : true; short stat_autoshutdowntime = packet.GetShort(); short stat_pensensitivity = packet.GetShort(); PenController.onReceivePenStatus(new PenStatusReceivedEventArgs(stat_timezone, stat_timetick, stat_forcemax, stat_battery, stat_usedmem, stat_pencolor, stat_autopower, stat_accel, stat_hovermode, stat_beep, stat_autoshutdowntime, stat_pensensitivity)); break; // 오프라인 데이터 크기,갯수 전송 case Cmd.A_OfflineDataInfo: mOfflineTotalFileCount = packet.GetInt(); mOfflineTotalDataSize = packet.GetInt(); Debug.WriteLine("[PenCommCore] A_OfflineDataInfo : {0}, {1}", mOfflineTotalFileCount, mOfflineTotalDataSize); PenController.onStartOfflineDownload(); IsStartOfflineTask = true; break; // 오프라인 전송 최종 결과 응답 case Cmd.A_OfflineResultResponse: int result = packet.GetByteToInt(); //System.Console.WriteLine( "[PenCommCore] A_OfflineDataResponse : {0}", result ); IsStartOfflineTask = false; PenController.onFinishedOfflineDownload(new SimpleResultEventArgs(result == 0x00)); mOfflineworker.onFinishDownload(); break; // 오프라인 파일 정보 case Cmd.A_OfflineFileInfo: mOfflineFileName = packet.GetString(128); mOfflineFileSize = packet.GetInt(); mOfflinePacketCount = packet.GetShort(); mOfflinePacketSize = packet.GetShort(); Debug.WriteLine("[PenCommCore] offline file transfer is started ( name : " + mOfflineFileName + ", size : " + mOfflineFileSize + ", packet_qty : " + mOfflinePacketCount + ", packet_size : " + mOfflinePacketSize + " )"); mOfflineDataBuilder = null; mOfflineDataBuilder = new OfflineDataSerializer(mOfflineFileName, mOfflinePacketCount, mOfflineFileName.Contains(".zip") ? true : false); SendOfflineInfoResponse(); break; // 오프라인 파일 조각 전송 case Cmd.A_OfflineChunk: int index = packet.GetShort(); // 체크섬 필드 byte cs = packet.GetByte(); // 체크섬 계산 byte calcChecksum = packet.GetChecksum(); // 오프라인 데이터 byte[] data = packet.GetBytes(); // 체크섬이 틀리거나, 카운트, 사이즈 정보가 맞지 않으면 버린다. if (cs == calcChecksum && mOfflinePacketCount > index && mOfflinePacketSize >= data.Length) { mOfflineDataBuilder.Put(data, index); // 만약 Chunk를 다 받았다면 offline data를 처리한다. if (mOfflinePacketCount == mOfflineDataBuilder.chunks.Count) { string output = mOfflineDataBuilder.MakeFile(); if (output != null) { SendOfflineChunkResponse((short)index); mOfflineworker.onCreateFile(mOfflineDataBuilder.sectionId, mOfflineDataBuilder.ownerId, mOfflineDataBuilder.noteId, output, mOfflineTotalDataSize, mOfflineRcvDataSize); } mOfflineDataBuilder = null; } else { SendOfflineChunkResponse((short)index); } mOfflineRcvDataSize += data.Length; // TODO Check //if (mOfflineTotalDataSize > 0) //{ // Debug.WriteLine("[PenCommCore] mOfflineRcvDataSize : " + mOfflineRcvDataSize); // //Callback.onUpdateOfflineDownload(this, mOfflineTotalDataSize, mOfflineRcvDataSize); //} } else { Debug.WriteLine("[PenCommCore] offline data file verification failed ( index : " + index + " )"); } break; case Cmd.A_UsingNoteNotifyResponse: PenController.onAvailableNoteAdded(); break; case Cmd.A_OfflineNoteListResponse: { int status = packet.GetByteToInt(); byte[] rxb = packet.GetBytes(4); int section = (int)(rxb[3] & 0xFF); int owner = ByteConverter.ByteToInt(new byte[] { rxb[0], rxb[1], rxb[2], (byte)0x00 }); int noteCnt = packet.GetByteToInt(); for (int i = 0; i < noteCnt; i++) { int note = packet.GetInt(); mOfflineNotes.Add(new OfflineDataInfo(section, owner, note)); } if (status == 0x01) { OfflineDataInfo[] array = mOfflineNotes.ToArray(); PenController.onReceiveOfflineDataList(new OfflineDataListReceivedEventArgs(array)); mOfflineNotes.Clear(); } else { PenController.onReceiveOfflineDataList(new OfflineDataListReceivedEventArgs(new OfflineDataInfo[0])); } } break; case Cmd.A_OfflineDataRemoveResponse: //System.Console.WriteLine( "[PenCommCore] CMD.A_OfflineDataRemoveResponse" ); break; case Cmd.A_PasswordRequest: { int countRetry = packet.GetByteToInt(); int countReset = packet.GetByteToInt(); Debug.WriteLine("[PenCommCore] A_PasswordRequest ( " + countRetry + " / " + countReset + " )"); PenController.onPenPasswordRequest(new PasswordRequestedEventArgs(countRetry, countReset)); } break; case Cmd.A_PasswordSetResponse: { int setResult = packet.GetByteToInt(); //System.Console.WriteLine( "[PenCommCore] A_PasswordSetResponse => " + setResult ); PenController.onPenPasswordSetupResponse(new SimpleResultEventArgs(setResult == 0x00)); } break; case Cmd.A_PenSensitivityResponse: case Cmd.A_AutoShutdownTimeResponse: case Cmd.A_AutoPowerOnResponse: case Cmd.A_BeepSetResponse: case Cmd.A_PenColorSetResponse: ResPenSetup((Cmd)packet.Cmd, packet.GetByteToInt() == 0x01); break; case Cmd.A_PenSWUpgradeRequest: short idx = packet.GetShort(); Debug.WriteLine("[PenCommCore] A_PenSWUpgradeRequest => " + idx); ResponseChunkRequest(idx); break; case Cmd.A_PenSWUpgradeStatus: { int upgStatus = packet.GetByteToInt(); if (upgStatus == 0x02) { return; } PenController.onReceiveFirmwareUpdateResult(new SimpleResultEventArgs(upgStatus == 0x01)); mFwChunk = null; } break; } }