processPacket method

int processPacket(
  1. DC msg,
  2. int offset,
  3. int ends,
  4. NetworkBuffer data,
  5. int chunkId,
)

Implementation

int processPacket(
    DC msg, int offset, int ends, NetworkBuffer data, int chunkId) {
  var packet = new IIPPacket();

  if (_ready) {
    //print("Inc " + msg.length.toString());

    var rt = packet.parse(msg, offset, ends);

    //print("Packet " + packet.toString());

    if (rt <= 0) {
      // print("hold");
      var size = ends - offset;
      data.holdFor(msg, offset, size, size - rt);
      return ends;
    } else {
      //print("CMD ${packet.command} ${offset} ${ends}");

      offset += rt;

      if (packet.command == IIPPacketCommand.Event) {
        switch (packet.event) {
          case IIPPacketEvent.ResourceReassigned:
            iipEventResourceReassigned(
                packet.resourceId, packet.newResourceId);
            break;
          case IIPPacketEvent.ResourceDestroyed:
            iipEventResourceDestroyed(packet.resourceId);
            break;
          case IIPPacketEvent.PropertyUpdated:
            iipEventPropertyUpdated(packet.resourceId, packet.methodIndex,
                packet.dataType ?? TransmissionType.Null, msg);
            break;
          case IIPPacketEvent.EventOccurred:
            iipEventEventOccurred(packet.resourceId, packet.methodIndex,
                packet.dataType ?? TransmissionType.Null, msg);
            break;

          case IIPPacketEvent.ChildAdded:
            iipEventChildAdded(packet.resourceId, packet.childId);
            break;
          case IIPPacketEvent.ChildRemoved:
            iipEventChildRemoved(packet.resourceId, packet.childId);
            break;
          case IIPPacketEvent.Renamed:
            iipEventRenamed(packet.resourceId, packet.resourceName);
            break;
          case IIPPacketEvent.AttributesUpdated:
            // @TODO: fix this
            //iipEventAttributesUpdated(packet.resourceId, packet.dataType. ?? TransmissionType.Null);
            break;
        }
      } else if (packet.command == IIPPacketCommand.Request) {
        switch (packet.action) {
          // Manage
          case IIPPacketAction.AttachResource:
            iipRequestAttachResource(packet.callbackId, packet.resourceId);
            break;
          case IIPPacketAction.ReattachResource:
            iipRequestReattachResource(
                packet.callbackId, packet.resourceId, packet.resourceAge);
            break;
          case IIPPacketAction.DetachResource:
            iipRequestDetachResource(packet.callbackId, packet.resourceId);
            break;
          case IIPPacketAction.CreateResource:

            // @TODO: Fix this
            //iipRequestCreateResource(packet.callbackId, packet.storeId,
            //  packet.resourceId, packet.content);
            break;
          case IIPPacketAction.DeleteResource:
            iipRequestDeleteResource(packet.callbackId, packet.resourceId);
            break;
          case IIPPacketAction.AddChild:
            iipRequestAddChild(
                packet.callbackId, packet.resourceId, packet.childId);
            break;
          case IIPPacketAction.RemoveChild:
            iipRequestRemoveChild(
                packet.callbackId, packet.resourceId, packet.childId);
            break;
          case IIPPacketAction.RenameResource:
            iipRequestRenameResource(
                packet.callbackId, packet.resourceId, packet.resourceName);
            break;

          // Inquire
          case IIPPacketAction.TemplateFromClassName:
            iipRequestTemplateFromClassName(
                packet.callbackId, packet.className);
            break;
          case IIPPacketAction.TemplateFromClassId:
            iipRequestTemplateFromClassId(packet.callbackId, packet.classId);
            break;
          case IIPPacketAction.TemplateFromResourceId:
            iipRequestTemplateFromResourceId(
                packet.callbackId, packet.resourceId);
            break;
          case IIPPacketAction.QueryLink:
            iipRequestQueryResources(packet.callbackId, packet.resourceLink);
            break;

          case IIPPacketAction.ResourceChildren:
            iipRequestResourceChildren(packet.callbackId, packet.resourceId);
            break;
          case IIPPacketAction.ResourceParents:
            iipRequestResourceParents(packet.callbackId, packet.resourceId);
            break;

          case IIPPacketAction.ResourceHistory:
            iipRequestInquireResourceHistory(packet.callbackId,
                packet.resourceId, packet.fromDate, packet.toDate);
            break;

          case IIPPacketAction.LinkTemplates:
            iipRequestLinkTemplates(packet.callbackId, packet.resourceLink);
            break;

          // Invoke
          case IIPPacketAction.InvokeFunction:
            iipRequestInvokeFunction(
                packet.callbackId,
                packet.resourceId,
                packet.methodIndex,
                packet.dataType ?? TransmissionType.Null,
                msg);
            break;

          case IIPPacketAction.Listen:
            iipRequestListen(
                packet.callbackId, packet.resourceId, packet.methodIndex);
            break;
          case IIPPacketAction.Unlisten:
            iipRequestUnlisten(
                packet.callbackId, packet.resourceId, packet.methodIndex);
            break;
/*
                      case IIPPacketAction.GetProperty:
                          iipRequestGetProperty(packet.callbackId, packet.resourceId, packet.methodIndex);
                          break;
                      case IIPPacketAction.GetPropertyIfModified:
                          iipRequestGetPropertyIfModifiedSince(packet.callbackId, packet.resourceId,
                                                                packet.methodIndex, packet.resourceAge);
                          break;
*/
          case IIPPacketAction.SetProperty:
            iipRequestSetProperty(
                packet.callbackId,
                packet.resourceId,
                packet.methodIndex,
                packet.dataType ?? TransmissionType.Null,
                msg);
            break;

          // Attribute
          case IIPPacketAction.GetAllAttributes:
            // @TODO: fix this
            //iipRequestGetAttributes(
            //  packet.callbackId, packet.resourceId, packet.content, true);
            break;
          case IIPPacketAction.UpdateAllAttributes:
            //iipRequestUpdateAttributes(
            //  packet.callbackId, packet.resourceId, packet.content, true);
            break;
          case IIPPacketAction.ClearAllAttributes:
            //iipRequestClearAttributes(
            //  packet.callbackId, packet.resourceId, packet.content, true);
            break;
          case IIPPacketAction.GetAttributes:
            //iipRequestGetAttributes(
            //  packet.callbackId, packet.resourceId, packet.content, false);
            break;
          case IIPPacketAction.UpdateAttributes:
            //iipRequestUpdateAttributes(
            //    packet.callbackId, packet.resourceId, packet.content, false);
            break;
          case IIPPacketAction.ClearAttributes:
            //iipRequestClearAttributes(
            //    packet.callbackId, packet.resourceId, packet.content, false);
            break;

          case IIPPacketAction.KeepAlive:
            iipRequestKeepAlive(
                packet.callbackId, packet.currentTime, packet.interval);
            break;

          case IIPPacketAction.ProcedureCall:
            iipRequestProcedureCall(packet.callbackId, packet.procedure,
                packet.dataType as TransmissionType, msg);
            break;

          case IIPPacketAction.StaticCall:
            iipRequestStaticCall(packet.callbackId, packet.classId,
                packet.methodIndex, packet.dataType as TransmissionType, msg);
            break;
        }
      } else if (packet.command == IIPPacketCommand.Reply) {
        switch (packet.action) {
          // Manage
          case IIPPacketAction.AttachResource:
            iipReply(packet.callbackId, [
              packet.classId,
              packet.resourceAge,
              packet.resourceLink,
              packet.dataType ?? TransmissionType.Null,
              msg
            ]);
            break;

          case IIPPacketAction.ReattachResource:
            iipReply(packet.callbackId, [
              packet.resourceAge,
              packet.dataType ?? TransmissionType.Null,
              msg
            ]);

            break;
          case IIPPacketAction.DetachResource:
            iipReply(packet.callbackId);
            break;

          case IIPPacketAction.CreateResource:
            iipReply(packet.callbackId, [packet.resourceId]);
            break;

          case IIPPacketAction.DeleteResource:
          case IIPPacketAction.AddChild:
          case IIPPacketAction.RemoveChild:
          case IIPPacketAction.RenameResource:
            iipReply(packet.callbackId);
            break;

          // Inquire

          case IIPPacketAction.TemplateFromClassName:
          case IIPPacketAction.TemplateFromClassId:
          case IIPPacketAction.TemplateFromResourceId:
            if (packet.dataType != null) {
              var content = msg.clip(packet.dataType?.offset ?? 0,
                  packet.dataType?.contentLength ?? 0);
              iipReply(packet.callbackId, [TypeTemplate.parse(content)]);
            } else {
              iipReportError(packet.callbackId, ErrorType.Management,
                  ExceptionCode.TemplateNotFound.index, "Template not found");
            }

            break;

          case IIPPacketAction.QueryLink:
          case IIPPacketAction.ResourceChildren:
          case IIPPacketAction.ResourceParents:
          case IIPPacketAction.ResourceHistory:
          case IIPPacketAction.LinkTemplates:
            iipReply(packet.callbackId,
                [packet.dataType ?? TransmissionType.Null, msg]);
            break;

          // Invoke
          case IIPPacketAction.InvokeFunction:
          case IIPPacketAction.StaticCall:
          case IIPPacketAction.ProcedureCall:
            iipReplyInvoke(packet.callbackId,
                packet.dataType ?? TransmissionType.Null, msg);
            break;

          // case IIPPacketAction.GetProperty:
          //   iipReply(packet.callbackId, [packet.content]);
          //   break;

          // case IIPPacketAction.GetPropertyIfModified:
          //   iipReply(packet.callbackId, [packet.content]);
          //   break;

          case IIPPacketAction.Listen:
          case IIPPacketAction.Unlisten:
          case IIPPacketAction.SetProperty:
            iipReply(packet.callbackId);
            break;

          // Attribute
          case IIPPacketAction.GetAllAttributes:
          case IIPPacketAction.GetAttributes:
            iipReply(packet.callbackId,
                [packet.dataType ?? TransmissionType.Null, msg]);
            break;

          case IIPPacketAction.UpdateAllAttributes:
          case IIPPacketAction.UpdateAttributes:
          case IIPPacketAction.ClearAllAttributes:
          case IIPPacketAction.ClearAttributes:
            iipReply(packet.callbackId);
            break;

          case IIPPacketAction.KeepAlive:
            iipReply(packet.callbackId, [packet.currentTime, packet.jitter]);
            break;
        }
      } else if (packet.command == IIPPacketCommand.Report) {
        switch (packet.report) {
          case IIPPacketReport.ManagementError:
            iipReportError(packet.callbackId, ErrorType.Management,
                packet.errorCode, null);
            break;
          case IIPPacketReport.ExecutionError:
            iipReportError(packet.callbackId, ErrorType.Exception,
                packet.errorCode, packet.errorMessage);
            break;
          case IIPPacketReport.ProgressReport:
            iipReportProgress(packet.callbackId, ProgressType.Execution,
                packet.progressValue, packet.progressMax);
            break;
          case IIPPacketReport.ChunkStream:
            iipReportChunk(packet.callbackId,
                packet.dataType ?? TransmissionType.Null, msg);
            break;
        }
      }
    }
  } else {
    var rt = _authPacket.parse(msg, offset, ends);

    if (rt <= 0) {
      data.holdForNeeded(msg, ends - rt);
      return ends;
    } else {
      offset += rt;

      if (_session?.localAuthentication.type == AuthenticationType.Host) {
        if (_authPacket.command == IIPAuthPacketCommand.Declare) {
          if (_authPacket.remoteMethod == AuthenticationMethod.Credentials &&
              _authPacket.localMethod == AuthenticationMethod.None) {
            /*
                          server.membership.userExists(_authPacket.remoteUsername, _authPacket.domain).then((x)
                          {
                              if (x)
                              {
                                  _session.remoteAuthentication.username = _authPacket.remoteUsername;
                                  _remoteNonce = _authPacket.remoteNonce;
                                  _session.remoteAuthentication.domain = _authPacket.domain;
                                  sendParams()
                                              .addUint8(0xa0)
                                              .addDC(_localNonce)
                                              .done();
                              }
                              else
                              {
                                  sendParams().addUint8(0xc0).addUint8(1).addUint16(14).addString("User not found").done();
                              }
                          });
                          */

          }
        } else if (_authPacket.command == IIPAuthPacketCommand.Action) {
          if (_authPacket.action == IIPAuthPacketAction.AuthenticateHash) {
            var remoteHash = _authPacket.hash;

            /*
                          server.membership.getPassword(_session.remoteAuthentication.username,
                                                        _session.remoteAuthentication.domain).then((pw)
                                                        {
                                                            if (pw != null)
                                                            {
                                                                //var hash = hashFunc.ComputeHash(BinaryList.ToBytes(pw, remoteNonce, localNonce));
                                                                var hash = SHA256.compute((new BinaryList())
                                                                                                  .addDC(pw)
                                                                                                  .addDC(_remoteNonce)
                                                                                                  .addDC(_localNonce)
                                                                                                  .toDC());
                                                                if (hash.sequenceEqual(remoteHash))
                                                                {
                                                                    // send our hash
                                                                    //var localHash = hashFunc.ComputeHash(BinaryList.ToBytes(localNonce, remoteNonce, pw));
                                                                    //SendParams((byte)0, localHash);

                                                                    var localHash = SHA256.compute
                                                                            ((new BinaryList()).addDC(_localNonce).addDC(_remoteNonce).addDC(pw).toDC());
                                                                    sendParams().addUint8(0).addDC(localHash).done();

                                                                    _readyToEstablish = true;
                                                                }
                                                                else
                                                                {
                                                                    sendParams().addUint8(0xc0).addUint8(1).addUint16(5).addString("Error").done();
                                                                }
                                                            }
                                                        });
                                                        */
          } else if (_authPacket.action ==
              IIPAuthPacketAction.NewConnection) {
            if (_readyToEstablish) {
              var r = new Random();

              var sid = DC(32);

              for (var i = 0; i < 32; i++) sid[i] = r.nextInt(255);
              _session?.id = sid;

              _sendParams()
                ..addUint8(0x28)
                ..addDC(sid)
                ..done();

              _ready = true;
              status = ConnectionStatus.Connected;

              _openReply?.trigger(true);
              _openReply = null;
              emitArgs("ready", []);
              //OnReady?.Invoke(this);
              // server.membership.login(session);

            }
          }
        }
      } else if (_session?.localAuthentication.type ==
          AuthenticationType.Client) {
        if (_authPacket.command == IIPAuthPacketCommand.Acknowledge) {
          if (_authPacket.remoteMethod == AuthenticationMethod.None) {
            _sendParams()
              ..addUint8(0x20)
              ..addUint16(0)
              ..done();
          } else if (_authPacket.remoteMethod ==
                  AuthenticationMethod.Credentials ||
              _authPacket.remoteMethod == AuthenticationMethod.Token) {
            _remoteNonce = _authPacket.remoteNonce;

            // send our hash
            var localHash = SHA256.compute((BinaryList()
                  ..addDC(_localPasswordOrToken as DC)
                  ..addDC(_localNonce as DC)
                  ..addDC(_remoteNonce as DC))
                .toDC());

            _sendParams()
              ..addUint8(0)
              ..addDC(localHash)
              ..done();
          }
          //SendParams((byte)0, localHash);
        } else if (_authPacket.command == IIPAuthPacketCommand.Action) {
          if (_authPacket.action == IIPAuthPacketAction.AuthenticateHash) {
            // check if the server knows my password
            var remoteHash = SHA256.compute((BinaryList()
                  ..addDC(_remoteNonce as DC)
                  ..addDC(_localNonce as DC)
                  ..addDC(_localPasswordOrToken as DC))
                .toDC());

            if (remoteHash.sequenceEqual(_authPacket.hash)) {
              // send establish request
              _sendParams()
                ..addUint8(0x20)
                ..addUint16(0)
                ..done();
            } else {
              _sendParams()
                ..addUint8(0xc0)
                ..addUint8(ExceptionCode.ChallengeFailed.index)
                ..addUint16(16)
                ..addString("Challenge Failed")
                ..done();

              //SendParams((byte)0xc0, 1, 5, DC.ToBytes("Error"));
            }
          } else if (_authPacket.action ==
              IIPAuthPacketAction.ConnectionEstablished) {
            _session?.id = _authPacket.sessionId;

            _ready = true;
            status = ConnectionStatus.Connected;

            _openReply?.trigger(true);
            _openReply = null;
            emitArgs("ready", []);

            // start perodic keep alive timer
            _keepAliveTimer = Timer(
                Duration(seconds: keepAliveInterval), _keepAliveTimerElapsed);
          }
        } else if (_authPacket.command == IIPAuthPacketCommand.Error) {
          _invalidCredentials = true;
          var ex = AsyncException(ErrorType.Management, _authPacket.errorCode,
              _authPacket.errorMessage);
          _openReply?.triggerError(ex);
          _openReply = null;
          emitArgs("error", [ex]);
          //OnError?.Invoke(this, authPacket.ErrorCode, authPacket.ErrorMessage);
          close();
        }
      }
    }
  }

  return offset;

  //if (offset < ends)
  //  processPacket(msg, offset, ends, data, chunkId);
}