Tái cấu trúc RIL

Android 7.0 đã tái cấu trúc Lớp Giao diện Vô tuyến (RIL) bằng cách sử dụng một bộ tính năng để cải thiện chức năng RIL. Cần phải thay đổi mã đối tác để triển khai các tính năng này. Đây là tùy chọn nhưng được khuyến khích. Các thay đổi về tái cấu trúc có khả năng tương thích ngược, do đó việc triển khai trước các tính năng được tái cấu trúc vẫn tiếp tục hoạt động.

Tái cấu trúc RIL bao gồm các cải tiến sau:

  • Mã lỗi RIL. Cho phép mã lỗi cụ thể ngoài mã GENERIC_FAILURE hiện có. Điều này hỗ trợ khắc phục sự cố lỗi bằng cách cung cấp thông tin cụ thể hơn về nguyên nhân gây ra lỗi.
  • Phiên bản RIL. Cung cấp thông tin phiên bản chính xác hơn và dễ dàng hơn để cấu hình.
  • Giao tiếp RIL bằng cách sử dụng Wakelocks. Cải thiện hiệu suất pin của thiết bị.

Bạn có thể thực hiện bất kỳ hoặc tất cả các cải tiến trên. Để biết thêm chi tiết, hãy tham khảo nhận xét mã về phiên bản RIL trong https://android.googlesource.com/platform/hardware/ril/+/main/include/telephony/ril.h .

Triển khai mã lỗi RIL nâng cao

Hầu như tất cả các cuộc gọi yêu cầu RIL đều có thể trả về mã lỗi GENERIC_FAILURE để phản hồi lại lỗi. Đây là sự cố với tất cả các phản hồi được yêu cầu do OEM trả về, điều này có thể gây khó khăn cho việc gỡ lỗi sự cố từ báo cáo lỗi nếu cùng một mã lỗi GENERIC_FAILURE được lệnh gọi RIL trả về vì các lý do khác nhau. Có thể mất nhiều thời gian để nhà cung cấp xác định phần nào của mã có thể trả về mã GENERIC_FAILURE .

Trong Android 7.x trở lên, OEM có thể trả về giá trị mã lỗi riêng biệt liên quan đến từng lỗi khác nhau hiện được phân loại là GENERIC_FAILURE . Các OEM không muốn tiết lộ công khai mã lỗi tùy chỉnh của mình có thể trả về lỗi dưới dạng một tập hợp số nguyên riêng biệt (chẳng hạn như 1 đến x) được ánh xạ là OEM_ERROR_1 đến OEM_ERROR_X . Nhà cung cấp phải đảm bảo rằng mỗi mã lỗi bị che giấu như vậy đều trả về bản đồ cho một lý do lỗi duy nhất trong mã. Việc sử dụng mã lỗi cụ thể có thể tăng tốc độ gỡ lỗi RIL bất cứ khi nào OEM trả về lỗi chung vì thường có thể mất quá nhiều thời gian để xác định nguyên nhân chính xác của mã lỗi GENERIC_FAILURE (và đôi khi không thể tìm ra).

Ngoài ra, ril.h bổ sung thêm nhiều mã lỗi cho enum RIL_LastCallFailCauseRIL_DataCallFailCause để mã nhà cung cấp có thể tránh trả về các lỗi chung như CALL_FAIL_ERROR_UNSPECIFIEDPDP_FAIL_ERROR_UNSPECIFIED .

Xác thực mã lỗi RIL nâng cao

Sau khi thêm mã lỗi mới để thay thế mã GENERIC_FAILURE , hãy xác minh mã lỗi mới được trả về bằng lệnh gọi RIL thay vì GENERIC_FAILURE .

Triển khai phiên bản RIL nâng cao

Việc tạo phiên bản RIL trong các bản phát hành Android cũ hơn có vấn đề: bản thân phiên bản không chính xác, cơ chế báo cáo phiên bản RIL không rõ ràng (khiến một số nhà cung cấp báo cáo phiên bản không chính xác) và cách giải quyết để ước tính phiên bản có xu hướng không chính xác.

Trong Android 7.x trở lên, ril.h ghi lại tất cả các giá trị phiên bản RIL, mô tả phiên bản RIL tương ứng và liệt kê tất cả các thay đổi cho phiên bản đó. Khi thực hiện các thay đổi tương ứng với phiên bản RIL, nhà cung cấp phải cập nhật phiên bản của họ bằng mã và trả lại phiên bản đó ở dạng RIL_REGISTER .

Xác thực phiên bản RIL nâng cao

Xác minh rằng phiên bản RIL tương ứng với mã RIL của bạn được trả về trong RIL_REGISTER (chứ không phải RIL_VERSION được xác định trong ril.h ).

Triển khai giao tiếp RIL bằng cách sử dụng Wakelocks

Khóa chế độ thức theo thời gian được sử dụng trong giao tiếp RIL một cách không chính xác, điều này ảnh hưởng tiêu cực đến hiệu suất của pin. Trong Android 7.x trở lên, bạn có thể cải thiện hiệu suất bằng cách phân loại các yêu cầu RIL và cập nhật mã để xử lý các khóa chế độ thức khác nhau cho các loại yêu cầu khác nhau.

Phân loại yêu cầu RIL

Các yêu cầu RIL có thể được yêu cầu hoặc không được yêu cầu. Nhà cung cấp nên phân loại thêm các yêu cầu được yêu cầu theo một trong các yêu cầu sau:

  • đồng bộ . Những yêu cầu không mất nhiều thời gian để phản hồi lại. Ví dụ: RIL_REQUEST_GET_SIM_STATUS .
  • không đồng bộ . Yêu cầu mất thời gian đáng kể để phản hồi lại. Ví dụ: RIL_REQUEST_QUERY_AVAILABLE_NETWORKS .

Các yêu cầu RIL được yêu cầu không đồng bộ có thể mất thời gian đáng kể. Sau khi nhận được xác nhận từ mã nhà cung cấp, RIL Java sẽ giải phóng khóa đánh thức, điều này có thể khiến bộ xử lý ứng dụng chuyển từ trạng thái không hoạt động sang trạng thái tạm dừng. Khi có phản hồi từ mã nhà cung cấp, RIL Java (bộ xử lý ứng dụng) sẽ lấy lại khóa đánh thức, xử lý phản hồi, sau đó trở về trạng thái không hoạt động. Việc chuyển từ trạng thái không hoạt động sang trạng thái tạm dừng sang trạng thái không hoạt động như vậy có thể tiêu tốn rất nhiều điện năng.

Nếu thời gian phản hồi không đủ dài, việc giữ khóa chế độ thức và ở chế độ chờ trong toàn bộ thời gian phản hồi có thể tiết kiệm điện hơn so với việc chuyển sang trạng thái tạm dừng bằng cách nhả khóa chế độ thức và thức dậy khi có phản hồi. Nhà cung cấp nên sử dụng các phép đo công suất dành riêng cho nền tảng để xác định giá trị ngưỡng của thời gian T khi công suất tiêu thụ khi ở chế độ không tải trong toàn bộ thời gian T lớn hơn công suất tiêu thụ khi chuyển từ không tải sang tạm dừng và sang không tải trong cùng thời gian T Khi biết thời gian T , các lệnh RIL mất nhiều thời gian T có thể được phân loại là không đồng bộ và các lệnh còn lại được phân loại là đồng bộ.

Kịch bản giao tiếp RIL

Các sơ đồ sau minh họa các kịch bản giao tiếp RIL phổ biến và cung cấp giải pháp sửa đổi mã để xử lý các yêu cầu được yêu cầu và không được yêu cầu của RIL.

Lưu ý: Để biết chi tiết triển khai về các hàm được sử dụng trong sơ đồ sau, hãy tham khảo các phương thức acquireWakeLock() , decrementWakeLock()clearWakeLock( ) trong ril.cpp .

Kịch bản: Yêu cầu RIL và yêu cầu phản hồi không đồng bộ

Trong trường hợp này, nếu phản hồi được yêu cầu RIL dự kiến ​​sẽ mất nhiều thời gian (tức là phản hồi cho RIL_REQUEST_GET_AVAILABLE_NETWORKS ), khóa đánh thức sẽ được giữ trong một thời gian dài ở phía bộ xử lý ứng dụng. Các vấn đề về modem cũng có thể khiến bạn phải chờ đợi lâu.

Hình 1. RIL yêu cầu phản hồi không đồng bộ.

Giải pháp 1: Modem giữ chế độ khóa chế độ thức cho yêu cầu RIL và phản hồi không đồng bộ.

Hình 2. Wakelock được giữ bởi modem.
  1. Yêu cầu RIL được gửi và modem thu được Wakelock để xử lý yêu cầu đó.
  2. Modem gửi xác nhận khiến phía Java giảm bộ đếm Wakelock và giải phóng nó khi giá trị bộ đếm bằng 0.

    Lưu ý: Khoảng thời gian chờ khóa đánh thức cho chuỗi yêu cầu-ack sẽ nhỏ hơn khoảng thời gian chờ hiện đang được sử dụng vì cần nhận được phản hồi khá nhanh.

  3. Sau khi xử lý yêu cầu, modem sẽ gửi một ngắt tới mã của nhà cung cấp có mã Wakelock và gửi phản hồi tới ril.cpp, mã này sẽ nhận được Wakelock và gửi phản hồi đến phía Java.
  4. Khi phản hồi đến phía Java, Wakelock sẽ được thu nhận và phản hồi sẽ được trả lại cho người gọi.
  5. Sau khi phản hồi được xử lý bởi tất cả các mô-đun, xác nhận sẽ được gửi (thông qua ổ cắm) trở lại ril.cpp , sau đó giải phóng Wakelock thu được ở bước 3.

Giải pháp 2: Modem không giữ được Wakelock và phản hồi nhanh (yêu cầu và phản hồi RIL đồng bộ). Hành vi đồng bộ và không đồng bộ được mã hóa cứng cho một lệnh RIL cụ thể và được quyết định trên cơ sở từng cuộc gọi.

Hình 3. Wakelock không được modem giữ.
  1. Yêu cầu RIL được gửi bằng cách gọi acquireWakeLock() ở phía Java.
  2. Mã nhà cung cấp không cần có Wakelock và có thể xử lý yêu cầu cũng như phản hồi nhanh chóng.
  3. Khi phía Java nhận được phản hồi, decrementWakeLock() được gọi, làm giảm bộ đếm Wakelock và giải phóng Wakelock nếu giá trị bộ đếm là 0.

Kịch bản: Phản hồi không mong muốn của RIL

Trong trường hợp này, các phản hồi không được yêu cầu của RIL có cờ loại khóa đánh thức trong đó cho biết liệu có cần lấy khóa đánh thức cho phản hồi của nhà cung cấp hay không. Nếu cờ được đặt, khóa đánh thức theo thời gian sẽ được đặt và phản hồi sẽ được gửi qua ổ cắm tới phía Java. Khi hết giờ, khóa đánh thức sẽ được giải phóng. Khóa đánh thức theo thời gian có thể quá dài hoặc quá ngắn đối với các phản hồi không được yêu cầu khác nhau của RIL.

Hình 4. Phản hồi không được yêu cầu của RIL.

Giải pháp: Một xác nhận được gửi từ mã Java đến phía gốc ( ril.cpp ) thay vì giữ một khóa đánh thức theo thời gian ở phía gốc trong khi gửi phản hồi không được yêu cầu.

Hình 5. Sử dụng ack thay vì khóa chế độ hẹn giờ.

Xác thực các khóa thức được thiết kế lại

Xác minh rằng các cuộc gọi RIL được xác định là đồng bộ hoặc không đồng bộ. Vì mức tiêu thụ năng lượng của pin có thể phụ thuộc vào phần cứng/nền tảng nên nhà cung cấp nên thực hiện một số thử nghiệm nội bộ để tìm hiểu xem việc sử dụng ngữ nghĩa Wakelock mới cho các cuộc gọi không đồng bộ có giúp tiết kiệm pin hay không.