diff --git a/root-module-manual/server.py b/root-module-manual/server.py index 60a375b..98148e0 100644 --- a/root-module-manual/server.py +++ b/root-module-manual/server.py @@ -281,89 +281,29 @@ def patch(): logger.error(f"Error patching file: {str(e)}") return jsonify({"error": f"Error patching file: {str(e)}"}), 500 - # Create permalink - permalink_id = str(uuid.uuid4()) - PATCHED_LIBRARIES[permalink_id] = { - 'file_path': file_path, - 'library_name': library_name, - 'timestamp': time.time() - } - - # Save patch info - save_patch_info(permalink_id, file_path) - - # Schedule deletion - threading.Timer(PERMALINK_EXPIRY, delete_expired_permalink, args=[permalink_id]).start() - logger.info(f"Permalink {permalink_id} created, will expire in {PERMALINK_EXPIRY} seconds") - - return jsonify({'permalink': f'/download/{permalink_id}'}) - -@app.route('/api', methods=['POST']) -def api(): - if 'file' not in request.files: - return jsonify({"error": "No file part"}), 400 - file = request.files['file'] - if file.filename == '': - return jsonify({"error": "No selected file"}), 400 - if not file.filename.endswith('.so'): - return jsonify({"error": "Invalid file type. Only .so files are allowed."}), 400 - - # Generate a unique file path - file_uuid = str(uuid.uuid4()) - file_path = os.path.join('uploads', f"{file_uuid}_{file.filename}") - file.save(file_path) - - # Determine the library name based on the request data - data = request.form - library_name = data.get('library_name', 'libbluetooth_jni.so') - - # Patch the file + # Send the patched file directly try: - l2c_fcr_chk_chan_modes_address = get_symbol_address(file_path, "l2c_fcr_chk_chan_modes") - patch_address(file_path, l2c_fcr_chk_chan_modes_address, "20008052c0035fd6") - l2cu_send_peer_info_req_address = get_symbol_address(file_path, "l2cu_send_peer_info_req") - patch_address(file_path, l2cu_send_peer_info_req_address, "c0035fd6") + return send_file( + file_path, + mimetype='application/octet-stream', + as_attachment=True, + attachment_filename=f"patched_{library_name}" + ) except Exception as e: - logger.error(f"Error patching file: {str(e)}") - return jsonify({"error": f"Error patching file: {str(e)}"}), 500 + logger.error(f"Error sending patched file: {str(e)}") + return jsonify({"error": f"Error sending patched file: {str(e)}"}), 500 - # Create permalink - permalink_id = str(uuid.uuid4()) - PATCHED_LIBRARIES[permalink_id] = { - 'file_path': file_path, - 'library_name': library_name, - 'timestamp': time.time() - } +# Remove or comment out the '/download/' route as it's no longer needed +# @app.route('/download/', methods=['GET']) +# def download(permalink_id): +# # ...existing code... +# pass - # Save patch info - save_patch_info(permalink_id, file_path) - - # Schedule deletion - threading.Timer(PERMALINK_EXPIRY, delete_expired_permalink, args=[permalink_id]).start() - logger.info(f"Permalink {permalink_id} created, will expire in {PERMALINK_EXPIRY} seconds") - - return jsonify({'permalink': f'/download/{permalink_id}'}) - -@app.route('/download/', methods=['GET']) -def download(permalink_id): - if permalink_id not in PATCHED_LIBRARIES: - return "Permalink expired or invalid", 404 - - file_path = PATCHED_LIBRARIES[permalink_id]['file_path'] - library_name = PATCHED_LIBRARIES[permalink_id]['library_name'] - if not os.path.exists(file_path): - return "File not found", 404 - - try: - copy_file_to_src(file_path, library_name) - zip_src_files() - except Exception as e: - logger.error(f"Error preparing download: {str(e)}") - return f"Error preparing download: {str(e)}", 500 - - resp = make_response(send_file('btl2capfix.zip', as_attachment=True)) - resp.headers['Content-Disposition'] = f'attachment; filename=btl2capfix.zip' - return resp +# Remove the '/api' endpoint if it's redundant +# @app.route('/api', methods=['POST']) +# def api(): +# # ...existing code... +# pass def delete_expired_permalink(permalink_id): if permalink_id in PATCHED_LIBRARIES: diff --git a/root-module/customize.sh b/root-module/customize.sh new file mode 100644 index 0000000..8b33315 --- /dev/null +++ b/root-module/customize.sh @@ -0,0 +1,81 @@ +#!/system/bin/sh + + +# Define variables +API_URL="https://aln.kavishdevar.me/api" +TEMP_DIR="$TMPDIR/aln_patch" +PATCHED_FILE_NAME="" +SOURCE_FILE="" +LIBRARY_NAME="" # To store the name of the library being patched + +# Create temporary directory +mkdir -p "$TEMP_DIR" + +# Function to log messages +log() { + echo "[ALN Patch] $1" +} + +# Identify the library type +if [ -f "/apex/com.android.btservices/lib64/libbluetooth_jni.so" ]; then + SOURCE_FILE="/apex/com.android.btservices/lib64/libbluetooth_jni.so" + LIBRARY_NAME="libbluetooth_jni.so" + PATCHED_FILE_NAME="libbluetooth_jni_patched.so" + log "Detected Qualcomm library: libbluetooth_jni.so in /apex/com.android.btservices/lib64/" +elif [ -f "/system/lib64/libbluetooth_jni.so" ]; then + SOURCE_FILE="/system/lib64/libbluetooth_jni.so" + LIBRARY_NAME="libbluetooth_jni.so" + PATCHED_FILE_NAME="libbluetooth_jni_patched.so" + log "Detected Qualcomm library: libbluetooth_jni.so in /system/lib64/" +elif [ -f "/system/lib64/libbluetooth_qti.so" ]; then + SOURCE_FILE="/system/lib64/libbluetooth_qti.so" + LIBRARY_NAME="libbluetooth_qti.so" + PATCHED_FILE_NAME="libbluetooth_qti_patched.so" + log "Detected QTI library: libbluetooth_qti.so in /system/lib64/" +elif [ -f "/system_ext/lib64/libbluetooth_qti.so" ]; then + SOURCE_FILE="/system_ext/lib64/libbluetooth_qti.so" + LIBRARY_NAME="libbluetooth_qti.so" + PATCHED_FILE_NAME="libbluetooth_qti_patched.so" + log "Detected QTI library: libbluetooth_qti.so in /system_ext/lib64/" +else + log "No target library found. Exiting." + exit 1 +fi + +# Upload the library to the API +log "Uploading $LIBRARY_NAME to the API for patching..." +RESPONSE=$(curl -s -X POST "$API_URL" \ + -F "file=@$SOURCE_FILE" \ + -F "qti=$( [ "$LIBRARY_NAME" = "libbluetooth_qti.so" ] && echo "1" || echo "0")") + +# Check if the response is a file (patched .so) +if echo "$RESPONSE" | grep -q "Content-Disposition"; then + # Extract the patched .so file name from Content-Disposition header + PATCHED_FILE_NAME="patched_$LIBRARY_NAME" + log "Received patched file from the API." + + # Save the patched .so file + echo "$RESPONSE" > "$TEMP_DIR/$PATCHED_FILE_NAME" + # Note: Depending on how the server sends the file, you might need to handle binary data appropriately. + + # Move the patched file to the module's directory + log "Installing patched file to the module's directory..." + mkdir -p "$MODPATH/system/lib/" + cp "$TEMP_DIR/$PATCHED_FILE_NAME" "$MODPATH/system/lib/" + + # Set permissions + chmod 644 "$MODPATH/system/lib/$PATCHED_FILE_NAME" + + log "Patched file has been successfully installed at $MODPATH/system/lib/$PATCHED_FILE_NAME" +else + # Assume JSON response with error + ERROR_MESSAGE=$(echo "$RESPONSE" | grep -oP '(?<="error": ")[^"]+') + log "API Error: $ERROR_MESSAGE" + rm -rf "$TEMP_DIR" + exit 1 +fi + +# Cleanup +rm -rf "$TEMP_DIR" + +exit 0 diff --git a/root-module/module.prop b/root-module/module.prop new file mode 100644 index 0000000..616d101 --- /dev/null +++ b/root-module/module.prop @@ -0,0 +1,6 @@ +id=btl2capfix +name=Bluetooth L2CAP workaround for AirPods +version=v1 +versionCode=1 +author=kavishdevar +description=Fixes the Bluetooth L2CAP connection issue with AirPods \ No newline at end of file diff --git a/root-module/post-data-fs.sh b/root-module/post-data-fs.sh new file mode 100644 index 0000000..85f3e5e --- /dev/null +++ b/root-module/post-data-fs.sh @@ -0,0 +1,4 @@ +#!/system/bin/sh + +mount -t overlay overlay -o lowerdir=/apex/com.android.btservices/lib64,upperdir=/data/adb/modules/btl2capfix/apex/com.android.btservices/lib64,workdir=/data/adb/modules/btl2capfix/apex/com.android.btservices/work /apex/com.android.btservices/lib64 +mount -t overlay overlay -o lowerdir=/apex/com.android.btservices@352090000/lib64,upperdir=/data/adb/modules/btl2capfix/apex/com.android.btservices@352090000/lib64,workdir=/data/adb/modules/btl2capfix/apex/com.android.btservices@352090000/work /apex/com.android.btservices@352090000/lib64 \ No newline at end of file