12.3. פורמט המנה¶
כל בייט שחוצה את התיל בין המצלמה למארח הוא חלק ממנה. מנה מתחילה בכותרת בת 10 בייטים, מריצה עומס מטען באורך משתנה, ומסתיימת ב-CRC סופי בן 4 בייטים. שום בייט אחר אינו מופיע על התיל – ברגע שהמארח ראה את מילת הסנכרון בת 2 הבייטים, הבייטים הבאים הם כותרת ברצף מדויק זה.
12.3.1. הכותרת¶
עשרה בייטים, ארוזים ללא ריפוד. כל שדה:
sync– המילה בת 16 הסיביות0xD5AAבסדר little-endian. בייט 0 על התיל הוא0xAA, בייט 1 הוא0xD5. מקבל הסורק בייטים יכול למצוא את תחילת המנה על ידי חיפוש הזוגAA D5; כל דבר שלפניו נחשב לזבל. בחירת הערך מכוונת:0xAAו-0xD5מופיעים לעיתים רחוקות בטקסט הניתן להדפסה, והזוג אינו צפוי להופיע במקרה באמצע עומס מטען.seq– בייט אחד. מונה שעולה באחד עבור כל מנה הנשלחת בכיוון נתון. המקבל בודק שמספר הרצף של המנה הבאה הוא הצפוי; אם לא, שכבת האמינות מבקשת שידור חוזר.chan– בייט אחד. מזהה הערוץ שאליו שייכת מנה זו. ערוצים 0..31 ניתנים לשימוש; הערוצים המובניםstdin,stdout,streamו-(אופציונלית)profileתופסים מזהים קבועים שהמצלמה שומרת.flags– בייט אחד. שדה-סיביות שמספר למקבל כיצד לפרש את המנה:סיבית 0
ACK– מנה זו היא אישור של מנה קודמת.סיבית 1
NAK– מנה זו דוחה מנה קודמת.סיבית 2
RTX– מנה זו היא שידור חוזר.סיבית 3
ACK_REQ– השולח רוצה שמנה זו תאושר.סיבית 4
FRAGMENT– מקטעים נוספים עוקבים אחר זה בהודעה גדולה יותר.סיבית 5
EVENT– מנה זו נושאת אירוע ערוץ ולא נתונים.סיביות 6 ו-7 שמורות.
opcode– בייט אחד. קוד הפקודה או התשובה. ספריית הפרוטוקול שומרת טווחי אופקוד לפי ייעוד:0x00..0x0F– פקודות פרוטוקול (SYNC, GET_CAPS, SET_CAPS, STATS, VERSION).0x10..0x1F– פקודות מערכת (RESET, BOOT, INFO, EVENT, MEMORY).0x20..0x2F– פקודות ערוץ (LIST, POLL, LOCK, UNLOCK, SHAPE, SIZE, READ, WRITE, IOCTL, EVENT).
len– שני בייטים, little-endian. מספר בייטים עומס המטען שעוקבים אחר הכותרת. אורך אפס הוא חוקי – אישורים רבים ופקודות קטנות אינם נושאים עומס מטען.crc– שני בייטים. CRC-16 על שמונת בייטים הכותרת הקודמים. מקבל שמקבל כותרת עם CRC שגוי משליך את כל המנה מבלי אפילו להביט בעומס המטען.
12.3.2. עומס המטען¶
אפס בייטים או יותר, מטופלים כאטומים על ידי שכבת המסגור. מה שנמצא בעומס המטען תלוי באופקוד: עבור תשובת CHANNEL_READ זה נתוני הערוץ בפועל; עבור תשובת GET_CAPS זה מבנה קבוע קטן; עבור כתיבת ערוץ זה כל מה שהמארח שלח.
גודל עומס המטען המרבי תלוי בגודל חוצץ הפרוטוקול של המצלמה (ראה את הטבלה לכל לוח ב-protocol.init()). הודעות ארוכות מהמכסה מפוצלות למקטעים כשהדגל FRAGMENT מוגדר בכולם מלבד האחרון.
12.3.3. ה-CRC הסופי¶
ארבעה בייטים, CRC-32 על עומס המטען. תופס השחתה שה-CRC של הכותרת אינו יכול לראות, בייחוד בעומסי מטען ארוכים שבהם שגיאת סיבית-בודדת באמצע מסגרת הייתה אחרת חומקת מבעד.
פיצול בדיקת השלמות בין שני CRC הוא מכוון. ה-CRC של הכותרת מגן על שדות המסגור עצמם – בייחוד על אורך עומס המטען. ללא CRC כותרת נפרד, היפוך סיבית בודד בבייט האורך היה גורם למקבל לקרוא את מספר הבייטים השגוי עבור עומס המטען ולצאת מסנכרון עם זרם הבייטים לחלוטין; עם אחד כזה, כותרת פגומה נדחית מיד והמקבל סורק מחדש אחר מילת הסנכרון הבאה. ה-CRC של עומס המטען מגן אז על גוף ההודעה כעניין נפרד, כך שהיפוך סיבית בנתונים מדווח כעומס מטען מושחת ולא נחשב בטעות לשגיאת מסגור.
הפורמט קטן מספיק כדי לעבור עליו בייט אחר בייט, והעובדה שלכל מנה יש אותה פריסה – סנכרון, אז כותרת, אז עומס מטען, אז CRC – משמעה שמנתח (parser) שנכתב ביד נכנס במסך אחד של קוד. זו הסיבה שמימוש מארח זעיר ב-C, Python או Rust הוא פרויקט של סוף שבוע; ספריית הפרוטוקול היא גרסת ה-Python המתוחזקת בכל צד.