Japan QualNet Community Forums Japan QualNet Community Forums
Welcome Guest 
ログイン
ユーザ名:

パスワード:


パスワード紛失

新規登録
検索
メインメニュー
アクセスカウンター
2025/04/29:14/18
2025/04/28:18/23

2025/03/07より259/1275
人気モジュール
No.1: フォーラム 42
No.2: QualNet概要 3
日曜日からの合計
人気Browser&OS
No.1:巡回ロボット31
No.2:Linux3
No.3:Macintosh2

No.1:どっかの巡回ロボット27
No.2:Safari6
No.3:Google巡回ロボット4

日曜日からの合計
メイン
   Link (MAC) Layer Settings
     MACとNetworkのクロスレイヤ設計について
投稿するにはまず登録を

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
Thams
投稿日時: 2008/9/22 23:58
半人前
登録日: 2007/10/3
居住地:
投稿: 26
MACとNetworkのクロスレイヤ設計について
以下の投稿を参照して、クロスレイヤ設計をしており、コーディングでわからない点があるので投稿させていただきます。
http://simweb.kke.co.jp/qualnet/forum/modules/newbb/viewtopic.php?topic_id=360&forum=29

まず、現状のコーディングについて
1.Message構造体にNetworkレイヤのヘッダポインタを格納するフィールドを追加

struct message_str
{
    Message*  next; // For kernel use only.
    ...
    // Users should not modify anything above this line.
    void *network_hdr         // Newly added
};


2.AODVのHELLOパケットのヘッダポインタを格納(routing_aodv.cpp)

static void AodvBroadcastHelloMessage(Node* node, AodvData* aodv, Address* destAddr)
{
  IPv6Data *ipv6 = (IPv6Data *) node->networkData.networkVar->ipv6;
  …
    int pktSize = sizeof(AodvRrepPacket)+sizeof(他の型)*listsize;(sizeof(他の型)*listsizeは、可変長のリスト)// Newly added
  …
  pktPtr += sizeof(AodvRrepPacket);// Newly added
    {
        rrepPkt = (AodvRrepPacket *) pktPtr;
        rrepPkt->typeBitsPrefixSizeHop = typeBitsPrefixSizeHop;
        rrepPkt->sourceAddr = ANY_IP;
        rrepPkt->destination.seqNum = aodv->seqNumber;
        rrepPkt->lifetime = lifetime;
     他の型 plus_info;// Newly added
     memcpy(pktPtr, &plus_info, sizeof(他の型));// Newly added
        pktPtr += sizeof(他の型);// Newly added
     }
     …
     clocktype delay =
            (clocktype) AODV_PC_ERAND(aodv->aodvJitterSeed);
     …
     newMsg->network_hdr = (char*) MESSAGE_ReturnPacket(newMsg);// Newly added
     …
     MESSAGE_Free(node, newMsg);// Newly added 箇所?
     …
}

*HELLOの受信側でもplus_info情報をテーブルに利用しています。

3.受信したノードのMAC層で情報を利用(mac_802_11.cpp)

void Mac802_11ReceivePacketFromPhy(
    Node* node,
    MacData802_11* M802,
    Message* msg)
{
…
    else if (hdr->destAddr == ANY_DEST) {
        switch (hdr->frameType) {
            case M802_11_DATA:
            case M802_11_CF_DATA_ACK: {
             AodvRrepPacket* helloPkt = (AodvRrepPacket*)msg->network_hdr;; // Newly added
             printf("MAC : hello packet source %d|%d received %d\n",helloPkt->helloSource.address,sourceNodeAddress,node->nodeId);// Newly added 箇所?
             printf("current msg = %d\n",M802->currentMessage->network_hdr);// Newly added 箇所?

*Mac802_11UpdateDirectionCacheWithCurrentSignal()関数でソースノード以外のノードもplus_info情報を用いて更新しています。


以上のような感じでコーディングをしており、箇所?で出力内容を確認すると、ソースノードのアドレスが一致しませんでした。
そのため、箇所?の出力を確認することで、現在処理されているメッセージと比較を試みましたが、
セグメンテーション違反になってしまいました。

どのようにすれば、箇所?でのソースノードアドレスの一致ができるようになるのでしょうか?
箇所?のFREEによる問題でしょうか?

ご指導お願いします。



実行の出力では、シミュレーション時間が戻ってしまうこともありました。

Current Sim Time[s] =    2.428660435  Real Time[s] =    0  Completed 21%
Current Sim Time[s] =    2.428704603  Real Time[s] =    0  Completed 22%
Current Sim Time[s] =    2.429144603  Real Time[s] =    0  Completed 23%
Current Sim Time[s] =    0.720000000  Real Time[s] =    0  Completed 24%
Current Sim Time[s] =    0.750000000  Real Time[s] =    0  Completed 25%
Current Sim Time[s] =    0.780000000  Real Time[s] =    0  Completed 26%
Current Sim Time[s] =    0.810000000  Real Time[s] =    0  Completed 27%
Current Sim Time[s] =    0.840000000  Real Time[s] =    0  Completed 28%
Current Sim Time[s] =    0.870000000  Real Time[s] =    0  Completed 29%
Current Sim Time[s] =    0.900000000  Real Time[s] =    0  Completed 30%
Current Sim Time[s] =    0.930000000  Real Time[s] =    0  Completed 31%
Current Sim Time[s] =    0.960000000  Real Time[s] =    0  Completed 32%
Current Sim Time[s] =    0.990000000  Real Time[s] =    0  Completed 33%
Current Sim Time[s] =    1.020000000  Real Time[s] =    0  Completed 34%
Current Sim Time[s] =    1.050000000  Real Time[s] =    0  Completed 35%
Current Sim Time[s] =    1.080000000  Real Time[s] =    0  Completed 36%
matumoto
投稿日時: 2008/9/25 12:30
一人前
登録日: 2008/5/13
居住地:
投稿: 80
Re: MACとNetworkのクロスレイヤ設計について
うーん、

> どのようにすれば、箇所(1)でのソースノードアドレスの一致ができるようになるのでしょうか?

と聞かれても、地道にデバッグして下さいとしかアドバイスできないのですが、少なくとも下記のようになるということは、

> 実行の出力では、シミュレーション時間が戻ってしまうこともありました。

明らかに書き換えてはいけないメモリを書き換えていると思います、ポインタ間違い、キャスト間違い、などなど。

それから、下記のprintfですが、ポインタを%d出力ですか?

> printf("current msg = %d\n",M802->currentMessage->network_hdr);

hed
投稿日時: 2008/9/25 15:15
一人前
登録日: 2006/7/3
居住地: 京都
投稿: 81
Re: MACとNetworkのクロスレイヤ設計について
Thamsさん、こんにちは

気づいた点を一つだけ。
引用:

実行の出力では、シミュレーション時間が戻ってしまうこともありました。


以前私も同様の現象が起きたことがあります。
その時はリビルドすることで、この現象はなくなりました。

まだ、この状況が再現され、なおかつリビルドしていない場合は、一度お試しください。
Thams
投稿日時: 2008/9/25 16:51
半人前
登録日: 2007/10/3
居住地:
投稿: 26
Re: MACとNetworkのクロスレイヤ設計について
matuさん、hedさん、コメントありがとうございます。

matuさん>
gdbでデバッグした結果、helloPkt->helloSource.addressとsourceNodeAddressでアドレスが異なっていたため、

newMsg->network_hdr = (char*) MESSAGE_ReturnPacket(newMsg);// Newly added

ポインタの取り方の時点で間違っていないかがわかればと思い質問させていただきました。

送信側のMAC層等でも確認したいと思います。

それから、ポインタは%dで出力しています。%xでもセグメンテーション違反になりましたが
、出力の型が何か思わしくなかったでしょうか?

hedさん>
make clean したのちに、makeし直しましたが、残念ながら結果は変わりませんでした。
ipoten
投稿日時: 2008/9/26 14:05
一人前
登録日: 2005/7/12
居住地:
投稿: 102
Re: MACとNetworkのクロスレイヤ設計について
こんにちは

引用:
箇所(3)のFREEによる問題でしょうか?
そのとおりだと思います。
この直前のMESSAGE_ReturnPacket(newMsg)は、単にnewMsg->packetを返すマクロです。
このpacketポインタが指す先は、メッセージ操作で必要に応じて確保されたり不要になったら解放してほかに使いまわされるようなメモリプール領域です。
MESSAGE_Free(node, newMsg)によって、newMsg->network_hdrが指す先は無効になっています。

パケットフィールドやメッセージのメンバ変数に、メッセージそのもののポインタを格納するのは基本的にNGです。
パケットメッセージがほかのノードに届くまでに、複数のコピー(基本的にはMESSAGE_Duplicate()が使用される)が発生し、コピー元のパケットメッセージはそれぞれのレイヤで任意に破棄されます。
パケットメッセージのコピーでは、ポインタが指す先の領域まではケアしてくれません。

クロスレイヤといってもMACとAODVの間であれば、MACヘッダとIPヘッダをはずすだけでAODVのメッセージを参照するのは比較的容易にできるのではないでしょうか。
基本的な手順としては、作業用にメッセージをコピー(MESSAGE_Duplicate())して、MACヘッダとIPヘッダをはずす。
以下は参考
    MESSAGE_RemoveHeader(node,
                         msg,
                         M802_11_DATA_FRAME_HDR_SIZE,
                         TRACE_802_11);
    NetworkIpRemoveIpHeader(
                            node,
                            msg,
                            &sourceAddress,
                            &destinationAddress,
                            &priority,
                            &ipProtocolNumber,
                            &ttl);

もちろんクロスレイヤなので、MACのフレームの種別、中身がIPv4かv6か、IPがフラグメントされていないか、IPの中身がAODVのメッセージかどうかをそれぞれの段階で確認する必要はあると思います。
実際にMACで受信してからAODVに上がるまでの処理を順におっていけば理解できると思いますよ?
Thams
投稿日時: 2008/9/26 15:10
半人前
登録日: 2007/10/3
居住地:
投稿: 26
Re: MACとNetworkのクロスレイヤ設計について
ipotenさん、ご指摘ありがとうございます。

メモリーの中身をコピーすることで解決することができました。

2.AODVのHELLOパケットのヘッダポインタを格納(routing_aodv.cpp)


static void AodvBroadcastHelloMessage(Node* node, AodvData* aodv, Address* destAddr)
{
  IPv6Data *ipv6 = (IPv6Data *) node->networkData.networkVar->ipv6;
  …
    int pktSize = sizeof(AodvRrepPacket)+sizeof(他の型)*listsize;(sizeof(他の型)*listsizeは、可変長のリスト)// Newly added
  …
    {
        rrepPkt = (AodvRrepPacket *) pktPtr;
        rrepPkt->typeBitsPrefixSizeHop = typeBitsPrefixSizeHop;
        rrepPkt->sourceAddr = ANY_IP;
        rrepPkt->destination.seqNum = aodv->seqNumber;
        rrepPkt->lifetime = lifetime;
        pktPtr += sizeof(AodvRrepPacket);// Newly added
     他の型 plus_info;// Newly added
     for(i=0;i<listsize;i++){// Newly added
     memcpy(pktPtr, &plus_info, sizeof(他の型));// Newly added
        pktPtr += sizeof(他の型);// Newly added
        }
     }
     …
     clocktype delay =
            (clocktype) AODV_PC_ERAND(aodv->aodvJitterSeed);
     …                                                               
     newMsg->network_hdr = malloc(pktSize);// Newly added             |
     pktPtr = (char *) MESSAGE_ReturnPacket(newMsg);// Newly added    |  メモリコピー
     memcpy(newMsg->network_hdr,pktPtr,pktSize);// Newly added        |
     …
     MESSAGE_Free(node, newMsg);// Newly added 箇所?
     …
}


パケットフィールドの方でも確認してみたいと思います。ありがとうございました。
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ
Copyright c KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.
XOOPS Cube PROJECT