Пример #1
0
        private Dot MakeDot(int owner, int section, int note, int page, long timestamp, float x, float y, int tiltX, int tiltY, int twist, int force, DotTypes type, int color)
        {
            Dot.Builder builder = new Dot.Builder();

            builder.owner(owner)
            .section(section)
            .note(note)
            .page(page)
            .timestamp(timestamp)
            .coord(x, y)
            .tilt(tiltX, tiltY)
            .twist(twist)
            .force(force)
            .dotType(type)
            .color(color);
            return(builder.Build());
        }
        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;
            }
        }