public static ArtNetObject decodeArtNetPacket(final byte[] packet, final InetAddress ip) {

		// The ArtNetPacket.
		final ArtNetObject artNetObject = null;

		// Set generals infos
		final String hexaBrut = byteArrayToHex(packet);
		final String id = new String(packet, 0, 7);
		
		// Extract OpCode
		int opCode = ((packet[9] & 0xFF) << 8) | (packet[8] & 0xFF);
		opCode = Integer.parseInt(Integer.toHexString(opCode));

		// Yes, it's a ArtNetPacket
		if (!"Art-Net".equals(id)) {
			return null;
		}

		/*
		 * Dicover the type of the packet.
		 * Please refer to OpcodeTable.
		 */
		if (OpCodeConstants.OPPOLL == opCode) {
			/*
			 * ArtPollPacket : This is an ArtPoll packet,
			 * no other data is contained in this UDP packet
			 */
			if (!checkVersion(packet, hexaBrut)) {
				return null;
			}
			return decodeArtPollPacket(packet, hexaBrut);
		} else if (OpCodeConstants.OPTIMECODE == opCode) {
			/*
			 * ArtTimePacket : OpTimeCode
			 * This is an ArtTimeCode packet.
			 * It is used to transport time code over the network.
			 */
			if (!checkVersion(packet, hexaBrut)) {
				return null;
			}
			return decodeArtTimeCodePacket(packet, hexaBrut);
		} else if (OpCodeConstants.OPPOLLREPLY == opCode) {
			// ArtPollReply : This is a ArtPollReply packet.
			return decodeArtPollReplyPacket(packet, hexaBrut, ip);
		} else if (OpCodeConstants.OPOUTPUT == opCode) {
			// ArtDMX
			return decodeArtDMXPacket(packet, hexaBrut);
		} else if (OpCodeConstants.ARTADDRESS == opCode) {
			// ArtAddress
			return decodeArtAddressPacket(packet, hexaBrut);
		}

		return artNetObject;
	}