docs: private void sendInitPacket(@NonNull final BluetoothGatt gatt, final boolean allowResume)
  			throws RemoteDfuException, DeviceDisconnectedException, DfuException, UploadAbortedException, UnknownResponseException {
  		final CRC32 crc32 = new CRC32(); // Used to calculate CRC32 of the Init packet
  		ObjectChecksum checksum;
  
  		// First, select the Command Object. As a response the maximum command size and information whether there is already
  		// a command saved from a previous connection is returned.
  		logi("Setting object to Command (Op Code = 6, Type = 1)");
  		final ObjectInfo info = selectObject(OBJECT_COMMAND);
  		logi(String.format(Locale.US, "Command object info received (Max size = %d, Offset = %d, CRC = %08X)", info.maxSize, info.offset, info.CRC32));
  		mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, String.format(Locale.US, "Command object info received (Max size = %d, Offset = %d, CRC = %08X)", info.maxSize, info.offset, info.CRC32));
  		//noinspection StatementWithEmptyBody
  		if (mInitPacketSizeInBytes > info.maxSize) {
  			// Ignore this here. Later, after sending the 'Create object' command, DFU target will send an error if init packet is too large
  		}
  
  		// Can we resume? If the offset obtained from the device is greater then zero we can compare it with the local init packet CRC
  		// and resume sending the init packet, or even skip sending it if the whole file was sent before.
  		boolean skipSendingInitPacket = false;
  		boolean resumeSendingInitPacket = false;
  		if (allowResume && info.offset > 0 && info.offset <= mInitPacketSizeInBytes) {
  			try {
  				// Read the same number of bytes from the current init packet to calculate local CRC32
  				final byte[] buffer = new byte[info.offset];
  				mInitPacketStream.read(buffer);
  				// Calculate the CRC32
  				crc32.update(buffer);
  				final int crc = (int) (crc32.getValue() & 0xFFFFFFFFL);
  
  				if (info.CRC32 == crc) {
  					logi("Init packet CRC is the same");
  					if (info.offset ==  mInitPacketSizeInBytes) {
  						// The whole init packet was sent and it is equal to one we try to send now.
  						// There is no need to send it again. We may try to resume sending data.
  						logi("-> Whole Init packet was sent before");
  						skipSendingInitPacket = true;
  						mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, "Received CRC match Init packet");
  					} else {
  						logi("-> " + info.offset + " bytes of Init packet were sent before");
  						resumeSendingInitPacket = true;
  						mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, "Resuming sending Init packet...");
  					}
  				} else {
  					// A different Init packet was sent before, or the error occurred while sending.
  					// We have to send the whole Init packet again.
  					mInitPacketStream.reset();
  					crc32.reset();
  					info.offset = 0;
  				}
  			} catch (final IOException e) {
  				loge("Error while reading " + info.offset + " bytes from the init packet stream", e);
  				try {
  					// Go back to the beginning of the stream, we will send the whole init packet
  					mInitPacketStream.reset();
  					crc32.reset();
  					info.offset = 0;
  				} catch (final IOException e1) {
  					loge("Error while resetting the init packet stream", e1);
  					mService.terminateConnection(gatt, DfuBaseService.ERROR_FILE_IO_EXCEPTION);
  					return;
  				}
  			}
  		}
  
  		if (!skipSendingInitPacket) {
  			// The Init packet is sent different way in this implementation than the firmware, and receiving PRNs is not implemented.
  			// This value might have been stored on the device, so we have to explicitly disable PRNs.
  			setPacketReceiptNotifications(0);
  			mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, "Packet Receipt Notif disabled (Op Code = 2, Value = 0)");
  
  			for (int attempt = 1; attempt <= MAX_ATTEMPTS;) {
  				if (!resumeSendingInitPacket) {
  					// Create the Init object
  					logi("Creating Init packet object (Op Code = 1, Type = 1, Size = " + mInitPacketSizeInBytes + ")");
  					writeCreateRequest(OBJECT_COMMAND, mInitPacketSizeInBytes);
  					mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, "Command object created");
  				}
  				// Write Init data to the Packet Characteristic
  				try {
  					logi("Sending " + (mInitPacketSizeInBytes - info.offset) + " bytes of init packet...");
  					writeInitData(mPacketCharacteristic, crc32);
  				} catch (final DeviceDisconnectedException e) {
  					loge("Disconnected while sending init packet");
  					throw e;
  				}
  				final int crc = (int) (crc32.getValue() & 0xFFFFFFFFL);
  				mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, String.format(Locale.US, "Command object sent (CRC = %08X)", crc));
  
  				// Calculate Checksum
  				logi("Sending Calculate Checksum command (Op Code = 3)");
  				checksum = readChecksum();
  				mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, String.format(Locale.US, "Checksum received (Offset = %d, CRC = %08X)", checksum.offset, checksum.CRC32));
  				logi(String.format(Locale.US, "Checksum received (Offset = %d, CRC = %08X)", checksum.offset, checksum.CRC32));
  
  				if (crc == checksum.CRC32) {
  					// Everything is OK, we can proceed
  					break;
  				} else {
  					if (attempt < MAX_ATTEMPTS) {
  						attempt++;
  						logi("CRC does not match! Retrying...(" + attempt + "/" + MAX_ATTEMPTS + ")");
  						mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_WARNING, "CRC does not match! Retrying...(" + attempt + "/" + MAX_ATTEMPTS + ")");
  						try {
  							// Go back to the beginning, we will send the whole Init packet again
  							resumeSendingInitPacket = false;
  							info.offset = 0;
  							info.CRC32 = 0;
  							mInitPacketStream.reset();
  							crc32.reset();
  						} catch (final IOException e) {
  							loge("Error while resetting the init packet stream", e);
  							mService.terminateConnection(gatt, DfuBaseService.ERROR_FILE_IO_EXCEPTION);
  							return;
  						}
  					} else {
  						loge("CRC does not match!");
  						mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_ERROR, "CRC does not match!");
  						mService.terminateConnection(gatt, DfuBaseService.ERROR_CRC_ERROR);
  						return;
  					}
  				}
  			}
  		}
  
  		// Execute Init packet. It's better to execute it twice than not execute at all...
  		logi("Executing init packet (Op Code = 4)");
  		writeExecute();
  		mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, "Command object executed");
  	}