אביזרי USB ל-Android חייבים לפעול בהתאם לפרוטוקול Android Open Accessory (AOA), שמגדיר את האופן שבו האביזר מזהה תקשורת עם מכשיר Android ומגדיר אותה. אביזרים צריכים לבצע את השלבים הבאים:
- מחכים למכשיר מחובר ומזהים אותו.
- בודקים אם יש תמיכה במצב אביזר במכשיר.
- מנסים להפעיל את המכשיר במצב אביזר (אם יש צורך).
- אם המכשיר תומך ב-AOA, יוצרים תקשורת עם המכשיר.
בקטעים הבאים מוסבר איך להטמיע את השלבים האלה.
המתנה לחיבור של מכשירים וזייהוי שלהם
האביזרים צריכים לבדוק באופן קבוע אם יש מכשירים מחוברים עם Android. כשמחברים מכשיר, האביזר צריך לקבוע אם המכשיר תומך במצב אביזר.
בדיקת התמיכה במצב אביזר
הערה: לא צריך ניפוי באגים ב-USB כדי לחבר אביזרים, אבל יכול להיות שתצטרכו להשתמש ב-ADB במהלך הפיתוח. לפרטים נוספים, ראו שיקולים לגבי ניפוי באגים.
כשמכשיר Android מתחבר, הוא יכול להיות באחד משלושת המצבים הבאים:
- יש תמיכה במצב אביזר ל-Android והמכשיר כבר נמצא במצב אביזר.
- יש תמיכה במצב אביזר ל-Android, אבל הוא לא במצב אביזר.
- אין תמיכה במצב אביזר ל-Android.
במהלך החיבור הראשוני, האביזר צריך לבדוק את הגרסה, מזהה הספק ומזהה המוצר של מתאר התקן ה-USB של המכשיר המחובר. מזהה הספק צריך להתאים למזהה של Google (0x18D1
). אם המכשיר כבר נמצא במצב אביזר, מזהה המוצר צריך להיות 0x2D00
או 0x2D01
והאביזר יכול ליצור תקשורת עם המכשיר דרך נקודות קצה להעברה בכמות גדולה באמצעות פרוטוקול התקשורת שלו (אין צורך להפעיל את המכשיר במצב אביזר).
הערה: השדה 0x2D00
מיועד למכשירים עם Android שתומכים במצב אביזר. 0x2D01
מוגדר למכשירים שתומכים במצב אביזר וגם בפרוטוקול Android Debug Bridge (ADB), שמציג ממשק שני עם שני נקודות קצה בכמות גדולה ל-ADB. אפשר להשתמש בנקודות הקצה האלה לניפוי באגים באפליקציית האביזר אם אתם מבצעים סימולציה של האביזר במחשב. באופן כללי, אין להשתמש בממשק הזה אלא אם האביזר מטמיע העברה ל-ADB במכשיר.
אם הגרסה, מזהה הספק או מזהה המוצר בתיאור של התקן ה-USB לא תואמים לערכים הצפויים, האביזר לא יוכל לקבוע אם המכשיר תומך במצב אביזר ל-Android. האביזר אמור לנסות להפעיל את המכשיר במצב אביזר (מפורט בהמשך) כדי לקבוע אם המכשיר נתמך.
נקודת מפתח: אביזרי USB חייבים לשלוח כותרת במהלך לחיצת היד הראשונית. הכותרת מכילה את היצרן, הדגם והגרסה. הגרסה היא שדה אופציונלי, אבל אם מותקנת אפליקציית Android שתואמת רק לגרסה, אבל האביזר לא שולח גרסה, מכשירי Android עם Android 10 וגרסאות ישנות יותר יופעלו מחדש בגלל חריגה שהושלחה בתהליך המערכת.
מנסים להפעיל את המכשיר במצב אביזר.
אם מזהי הגרסה, הספק והמוצר לא תואמים למכשיר עם Android במצב אביזר, האביזר לא יכול לקבוע אם המכשיר תומך במצב אביזר (אבל לא נמצא במצב כזה) או אם המכשיר לא תומך במצב אביזר. הסיבה לכך היא שמכשירים שתומכים במצב אביזר (אבל לא נמצאים במצב אביזר) מדווחים בהתחלה על מזהי המוצר והספק של יצרן המכשיר במקום על מזהי המוצר והספק של AOA.
האביזר צריך לנסות להפעיל את המכשיר במצב אביזר כדי לקבוע אם המכשיר תומך במצב הזה:
- שולחים בקשת בקרה 51 ('Get Protocol') כדי לקבוע אם המכשיר תומך בפרוטוקול של אביזר Android. אם המכשיר תומך בפרוטוקול, הוא מחזיר מספר שאינו אפס שמייצג את גרסת הפרוטוקול הנתמכת.
בקשת הבקרה נמצאת בנקודת הקצה 0 עם המאפיינים הבאים:
requestType: USB_DIR_IN | USB_TYPE_VENDOR request: 51 value: 0 index: 0 data: protocol version number (16 bits little endian sent from the device to the accessory)
- אם המכשיר מחזיר גרסת פרוטוקול נתמכת, שולחים למכשיר בקשת בקרה עם מידע על מחרוזת מזהה. המידע הזה מאפשר למכשיר לקבוע איזו אפליקציה מתאימה לשימוש עם האביזר (או להציג למשתמש כתובת URL אם אין אפליקציה מתאימה). בקשת הבקרה נמצאת בנקודת הקצה 0 (לכל מזהה מחרוזת) עם המאפיינים הבאים:
requestType: USB_DIR_OUT | USB_TYPE_VENDOR request: 52 value: 0 index: string ID data zero terminated UTF8 string sent from accessory to device
יש תמיכה במזהי המחרוזות הבאים, עם גודל מקסימלי של 256 בייטים לכל מחרוזת (חייבת להסתיים באפס עם
\0
).manufacturer name: 0 model name: 1 description: 2 version: 3 URI: 4 serial number: 5
- שולחים בקשת בקרה כדי לבקש מהמכשיר להתחיל במצב אביזר. בקשת הבקרה נמצאת בנקודת הקצה 0 עם המאפיינים הבאים:
requestType: USB_DIR_OUT | USB_TYPE_VENDOR request: 53 value: 0 index: 0 data: none
אחרי ביצוע השלבים האלה, האביזר אמור להמתין עד שמכשיר ה-USB המחובר יציג את עצמו מחדש באוטובוס במצב אביזר, ואז להכין רשימה מחדש של המכשירים המקושרים. כדי לקבוע אם יש תמיכה במצב אביזר, האלגוריתם בודק את מזהי הספק והמוצר, שצריכים להיות נכונים (למשל, תואמים למזהי הספק והמוצר של Google במקום למזהים של יצרן המכשיר). אם המזהים והגרסה נכונים, האביזר עובר לשלב יצירת תקשורת עם המכשיר.
הערה: בשלב הזה אין תמיכה ב-AOA בחיבורים בו-זמניים של AOA ו-MTP. כדי לעבור מ-AOA ל-MTP, צריך קודם לנתק את התקן ה-USB מהאביזר (פיזית או באופן שווה ערך מבחינה חשמלית) ואז לחבר אותו מחדש באמצעות MTP.
אם אחד מהשלבים נכשל, האביזר קובע שהמכשיר לא תומך במצב אביזר ל-Android וממתין לחיבור של המכשיר הבא.
יצירת תקשורת עם המכשיר
אם האביזר מזהה מכשיר Android במצב אביזר, הוא יכול לשלוח שאילתה לממשק המכשיר ולתיאורי נקודות הקצה כדי לקבל את נקודות הקצה הראשיות לצורך תקשורת עם המכשיר.
מספר הממשקים ונקודות הקצה בכמות גדולה תלוי במזהה המוצר. מכשיר Android עם מזהה מוצר:
- ל-
0x2D00
יש ממשק אחד עם שתי נקודות קצה ראשיות לתקשורת קלט ופלט. - ל-
0x2D01
יש שני ממשקים עם שתי נקודות קצה ראשיות (bulk) לכל אחד, לתקשורת קלט ופלט. הממשק הראשון מטפל בתקשורת רגילה והממשק השני מטפל בתקשורת ADB. כדי להשתמש בממשק, מאתרים את נקודות הקצה הראשונות של הקלט והפלט בכמות גדולה, מגדירים את הגדרת המכשיר לערך 1 באמצעות בקשת מכשירSET_CONFIGURATION
(0x09
), ולאחר מכן מתקשרים באמצעות נקודות הקצה.