AV / Cフレームを頻繁に操作する場合は、構造体を作成するのではなく(部分バイトのパッキングにはあまり役立ちません)、AVCFrame
これらのフレームを簡単にセットアップできるクラスを作成する必要があります。 、sanityは指定された値をチェックし、デバッグの説明があり、すべての汚れた詳細を処理します。
コードは次のようになります。
AVCFrame *frame = [AVCFrame frameWithCommandType:AVCCommandTypePlay
subunitType:mySubunitType
subunitID:mySubunitID];
// You likely won't actually be writing to the L2CAPChannel. See below.
[l2capChannel writeAsync:[frame mutableBytes] length:[frame length] refcon:nil];
それは最高のインターフェースではありません。AV/Cデジタルインターフェイスコマンドセットの一般仕様をお読みください。
バイトパッキングに関する限り(そして最終的には発生する必要があります)、次のようなものを使用する必要があります。
// Returns |subunitType| shifted and masked appropriately for bit_oring
// with subunit ID to create an address octet.
inline UInt8
AVRCAddressSubunitType(UInt8 subunitType) {
const UInt8 kLeastThreeBytes = 0x07;
UInt8 shiftedType = (subunitType << 3) & ~kLeastThreeBytes;
return shiftedType;
}
// Returns |subunitID| masked appropriately for bit_oring with subunit type
// to create an address octet.
inline UInt8
AVRCAddressSubunitID(UInt8 subunitID) {
const UInt8 kLeastThreeBytes = 0x07;
UInt8 maskedID = subunitID & kLeastThreeBytes;
if (subunitID & ~kLeastThreeBytes) {
NSLog(@"*** %s: subunit ID %#hhx > 0x07 cannot be represented "
"in the 3 bits allotted. Truncating to %#hhx.",
__PRETTY_FUNCTION__, subunitID, maskedID);
}
return maskedID;
}
- (void)l2capChannelOpenComplete:(IOBluetoothL2CAPChannel *)l2capChannel
status:(IOReturn)error {
/* might be worth looking at the error... */
NSLog(@"%s: open complete - "
"error: (system: %#x; subsystem: %#x; code: %#x)",
__PRETTY_FUNCTION__,
err_get_system(error), err_get_sub(error), err_get_code(error));
/* to send, first pack your data into byte-sized variables */
// some variables...
// address byte layout is [3:7] = 9 = PANEL; [0:2] = 0 = subunit ID
UInt8 address = (AVRCAddressSubunitType(0x09) | AVRCAddressSubunitID(0x00));
// some more variables...
/* create a mutable data and append the bytes in sequence */
// some appending...
[playData appendBytes:&address length:sizeof(address)];
// more appending...
/* finally, send all the bytes */
[l2capChannel writeAsync:[playData mutableBytes]
length:[playData length]
refcon:NULL];
}
の詳細についてはIOWhatever
、広範なIOKitドキュメントを参照してください。少なくとも10.5では、ドキュメントセット内の(プログラミングガイドではなく)リファレンスドキュメントはやや厄介だったので、ヘッダー自体をよく見ることができます。
これまでに見たよりも多くのドキュメントを参照する必要があります。ダイアグラムを含めたAV/Cコマンドフレームは、実際にはAVCTPフレームのペイロード([コマンド/応答メッセージ情報]フィールドに表示されます)であり、これは実際にL2CAPトランスポートを介して送信する必要があります。AVCTP仕様は、「付録A、AVCTP上位インターフェース」の基本的なAPIをスケッチしています。
AV / Cコマンドフレームを送信するには、AVCTPライブラリを見つけるか自分で作成する必要があります。AVCTPライブラリでL2CAPチャネルをラップして、実際にAVCTPライブラリを介してコマンドフレームを送信し、そこからコマンドフレームを受信できるようにする必要があります。幸運を!ハードウェアとのインターフェースはとても楽しいものであり、多くのことを学ぶことができます。