Пример #1
0
        protected async Task <IOTPResponse> ExecuteCommand(IOTPCommand command)
        {
            //send Command-begin request with command type
            await CommHelper.SendRequest(ReqType.Command, reqLCG.GenerateValue(), new byte[1] {
                command.CommandType
            }, 0, 1);

            //receive OK answer
            await ReceiveOkAnswer();

            //transfer command-data
            var cmdData  = command.SerializedData;
            var dataLeft = cmdData.Length;

            while (dataLeft > 0)
            {
                var dataLen = dataLeft;
                if (dataLen > Config.CMD_MAX_PLSZ)
                {
                    dataLen = Config.CMD_MAX_PLSZ;
                }
                //send CommandData request
                await CommHelper.SendRequest(ReqType.CommandData, reqLCG.GenerateValue(), cmdData, cmdData.Length - dataLeft, dataLen);

                //receive OK answer
                await ReceiveOkAnswer();

                dataLeft -= dataLen;
            }
            PreCommandCommit();
            //send Command-commit request
            await CommHelper.SendRequest(ReqType.Command, reqLCG.GenerateValue(), new byte[1] {
                0
            }, 0, 1);

            //receive OK answer
            await ReceiveOkAnswer();

            PostCommandCommit();
            //request response from device
            await CommHelper.SendRequest(ReqType.DataRequest, reqLCG.GenerateValue(), new byte[1] {
                0
            }, 0, 1);

            //receive dataMarker answer, that contains information about pending response
            var answer = await CommHelper.ReceiveAnswer();

            if (answer.ansType != AnsType.DataMarker)
            {
                throw new Exception($"Received non DataMarker answer: {answer.ansType}");
            }
            if (answer.seq != ansLCG.GenerateValue())
            {
                throw new Exception("Sequence number mismatch in DataMarker answer");
            }
            var respType = answer.payload[0];
            //receive data fragments
            var totalResponseSz   = 0;
            var responseFragments = new List <byte[]>();

            while (totalResponseSz < Config.MAX_RESPONSE_SZ)
            {
                //request response-data from device
                await CommHelper.SendRequest(ReqType.DataRequest, reqLCG.GenerateValue(), new byte[1] {
                    1
                }, 0, 1);

                //receive answer, that contains data chunk
                answer = await CommHelper.ReceiveAnswer();

                if (answer.ansType != AnsType.Data)
                {
                    throw new Exception($"Received non Data answer: {answer.ansType}");
                }
                if (answer.seq != ansLCG.GenerateValue())
                {
                    throw new Exception("Sequence number mismatch in DataMarker answer");
                }
                //generate response=object
                if (answer.payload.Length == 0)
                {
                    var serializedData = new byte[totalResponseSz];
                    var serializedPos  = 0;
                    foreach (var frag in responseFragments)
                    {
                        Buffer.BlockCopy(frag, 0, serializedData, serializedPos, frag.Length);
                        serializedPos += frag.Length;
                    }
                    return(ResponseHelper.DeserializeResponse(respType, serializedData));
                }
                responseFragments.Add(answer.payload);
                totalResponseSz += answer.payload.Length;
            }
            throw new Exception("Response data size reached!");
        }