📄 dmtpclientpackethandler.java
字号:
return null; } /* handle specific packet type */ Payload payload = packet.getPayload(true); switch (packet.getPacketType()) { /* client is done talking and is waiting for server response */ case Packet.PKT_CLIENT_EOB_DONE: case Packet.PKT_CLIENT_EOB_MORE: { // send responses, or close boolean clientHasMore = (packet.getPacketType() == Packet.PKT_CLIENT_EOB_MORE); java.util.List<Packet> resp = new Vector<Packet>(); // check checksum (if binary encoding) if (this.encoding == Encoding.ENCODING_BINARY) { if (packet.getPayloadLength() == 0) { // checksum not specified //Print.logInfo("Client checksum not specified"); } else if (packet.getPayloadLength() == 2) { if (!this.fletcher.isValid()) { Print.logError("Fletcher checksum is INVALID!!"); throw new PacketParseException(ServerErrors.NAK_BLOCK_CHECKSUM, packet); // errData ok } } else { throw new PacketParseException(ServerErrors.NAK_PACKET_PAYLOAD, packet); // errData ok } } this.fletcher.reset(); // acknowledge sent events if (this.lastValidEvent != null) { // at least 1 event has been received Packet ackPkt = Packet.createServerPacket(Packet.PKT_SERVER_ACK); int seqLen = this.lastValidEvent.getSequenceLength(); if (seqLen > 0) { long seq = this.lastValidEvent.getSequence(); ackPkt.getPayload(true).writeLong(seq, seqLen); } resp.add(ackPkt); this.eventBlockCount = 0; this.lastValidEvent = null; } // send any event parsing error packet if (this.eventErrorPacket != null) { resp.add(this.eventErrorPacket); this.eventErrorPacket = null; } // clear any previously transmitted PendingPackets this._clearPendingPackets(); // send any pending configuration packets // TODO: do we want to skip sending pending packets if we have an error? boolean serverSentPending = false; if (this.sendPending) { // until we know that we have no more pending packets this.pendingPackets = this.getDeviceId().getPendingPackets(); if (this.pendingPackets != null) { Packet p[] = this.pendingPackets.getPackets(); // will not be null Print.logInfo("Adding PendingPacket's to response [cnt=" + p.length + "]"); ListTools.toList(p, resp); serverSentPending = true; // TODO: Need to record that pending-packets are being (or have been) sent. //this._clearPendingPackets(); } else { // no more pending packets to send //Comment this line to contually check for PendingPackets //this.sendPending = false; } } // end-of-block / end-of-transmission if (clientHasMore || serverSentPending || this.expectEventTemplate) { // If 'serverSentPending' is true, we need to allow the client to respond Packet eobPkt = Packet.createServerPacket(Packet.PKT_SERVER_EOB_DONE); resp.add(eobPkt); if (this.expectEventTemplate) { // The client is given one opportunity for providing the event template // (this section will be exectued at-most once per session, and only if duplex) this.expectEventTemplate = false; } } else { Packet eotPkt = Packet.createServerPacket(Packet.PKT_SERVER_EOT); resp.add(eotPkt); this._setTerminateSession(); // success // we're done communicating with this client } return (Packet[])ListTools.toArray(resp, Packet.class); } /* client sent Unique-ID */ case Packet.PKT_CLIENT_UNIQUE_ID: { // lookup unique id try { // typically this should be 6 bytes, but we attempt to read 20 in case // the client wishes to provide additional information. byte uniqId[] = payload.readBytes(20); this.loadUniqueID(ipAddr, uniqId); } catch (PacketParseException ppe) { ppe.setTerminate(); throw ppe; } break; } /* client sent Account-ID */ case Packet.PKT_CLIENT_ACCOUNT_ID: { // lookup account try { String acctName = payload.readString(20); this.loadAccountId(ipAddr, acctName); } catch (PacketParseException ppe) { ppe.setTerminate(); throw ppe; } break; } /* client sent Device-ID */ case Packet.PKT_CLIENT_DEVICE_ID: { // lookup device try { String devName = payload.readString(20); if (this.accountId != null) { // normal Account/Device name lookup this.loadDeviceId(ipAddr, devName); } else { // an Account was not specified, try 'devName' as a Unique ID this.loadUniqueID(ipAddr, StringTools.getBytes(devName)); } } catch (PacketParseException ppe) { ppe.setTerminate(); throw ppe; } break; } /* client sent property value */ case Packet.PKT_CLIENT_PROPERTY_VALUE: { int propKey = (int)payload.readULong(2); byte propVal[] = payload.readBytes(255); // save property value sent by client, for later analysis this.getDeviceId().handleProperty(propKey, propVal); break; } /* client sent format definition template */ case Packet.PKT_CLIENT_FORMAT_DEF_24: { this.formatRecvTemplate++; // number of templates received // validate type int custType = (int)payload.readULong(1); Payload p = new Payload(); p.writeULong(custType, 1); if (!Packet.isCustomEventType(custType)) { byte errData[] = p.getBytes(); throw new PacketParseException(ServerErrors.NAK_FORMAT_DEFINITION_INVALID, packet, errData); // formatType } // validate that the payload size can accomodate the specified number of fields int numFlds = (int)payload.readULong(1); if (!payload.isValidReadLength(numFlds * 3)) { // not enough data to fill all specified field templates byte errData[] = p.getBytes(); throw new PacketParseException(ServerErrors.NAK_FORMAT_DEFINITION_INVALID, packet, errData); // formatType } // parse field templates PayloadTemplate.Field field[] = new PayloadTemplate.Field[numFlds]; int accumLen = 0; for (int i = 0; i < field.length; i++) { long fldMask = payload.readULong(3); field[i] = new PayloadTemplate.Field(fldMask); if (!field[i].isValidType()) { byte errData[] = p.getBytes(); throw new PacketParseException(ServerErrors.NAK_FORMAT_DEFINITION_INVALID, packet, errData); // formatType } accumLen += field[i].getLength(); if (accumLen > Packet.MAX_PAYLOAD_LENGTH) { byte errData[] = p.getBytes(); throw new PacketParseException(ServerErrors.NAK_FORMAT_DEFINITION_INVALID, packet, errData); // formatType } } PayloadTemplate payloadTemp = new PayloadTemplate(custType, field); this.getDeviceId().addClientPayloadTemplate(payloadTemp); break; } /* client sent diagnostic information */ case Packet.PKT_CLIENT_DIAGNOSTIC: { // log diagnostic int diagCode = (int)payload.readULong(2); byte diagData[] = payload.readBytes(255); this.getDeviceId().handleDiagnostic(diagCode, diagData); break; } /* client sent error code */ case Packet.PKT_CLIENT_ERROR: { // handle error int errCode = (int)payload.readULong(2); byte errData[] = payload.readBytes(255); this.getDeviceId().handleError(errCode, errData); return this._handleError(packet); } /* unknown/unsupported client packet */ default: { // generate error throw new PacketParseException(ServerErrors.NAK_PACKET_TYPE, packet); // errData ok } } return null; } // ------------------------------------------------------------------------ private Packet[] _parsePacket(String ipAddr, byte pkt[]) { // 'pkt' always represents a single packet /* Running Fletcher checksum */ this.fletcher.runningChecksum(pkt); /* print packet */ if ((pkt != null) && (pkt.length > 0)) { if (pkt[0] == Encoding.AsciiEncodingChar) { int len = (pkt[pkt.length - 1] == Encoding.AsciiEndOfLineChar)? (pkt.length - 1) : pkt.length; Print.logDebug("<== " + StringTools.toStringValue(pkt, 0, len)); } else { String encPkt = StringTools.toHexString(pkt); Print.logDebug("<== 0x" + encPkt); } } /* parse packet */ Packet packet = null; try { /* parse packet */ // Note: 'this.deviceId' may be null here (eg. before device is defined) // The device id is only needed for custom payload templates when parsing // custom events. packet = new Packet(this.deviceId, true, pkt); // client packet if (this.encoding == Encoding.ENCODING_UNKNOWN) { // The first received packet establishes the encoding this.encoding = packet.getEncoding(); } /* handle client packet, return response packets */ Packet p[] = this._handlePacket(ipAddr, packet); return p; } catch (PacketParseException ppe) { /* set packet if null */ Packet errPkt = ppe.getPacket(); if (errPkt == null) { ppe.setPacket(packet); errPkt = packet; } /* terminate? */ if (ppe.terminateSession()) { this._setTerminateSession(); // error } /* avoid duplicate NAK_FORMAT_NOT_RECOGNIZED error codes */ int errCode = ppe.getErrorCode(); if (errCode == ServerErrors.NAK_FORMAT_NOT_RECOGNIZED) { if (++this.formatErrorCount == 1) { // This section will be executed at-most once during a session if (errPkt != null) { // save first custom packet type found this.formatErrorType = errPkt.getPacketType(); if (this.isDuplex()) { // This is only a warning for Duplex communication int hdrType = (errPkt.getPacketHeader() << 8) | errPkt.getPacketType(); String hdrTypeStr = StringTools.toHexString(hdrType,16); Print.logWarn("Unrecognized event packet type: 0x" + hdrTypeStr + " (client will be notified)"); // we're now expecting an event template response from the client if (DMTPServer.getAllowFirstSessionNegotiation()) { this.expectEventTemplate = true; } } else { // This is an error for Simplex communication Print.logException("Unrecognized event packet type during Simplex transport!", ppe); } } else { // will not occur this.formatErrorType = 0; } } else if ((errPkt != null) && (errPkt.getPacketType() == this.formatErrorType)) { // we've already received a format error for this packet type, // do not send duplicates. return null; } } else { Print.logException("Error: ", ppe); } /* return error packet */ return new Packet[] { ppe.createServerErrorPacket() }; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -