Пример #1
0
void NodeData::make_reTransMsg(Node* node, CcnMsg* ccnMsg) {
  Message* timeoutMsg;
  AppTimer* info;
  timeoutMsg = MESSAGE_Alloc(
                          node,
                          APP_LAYER,
                          APP_CCN_HOST,
                          MSG_APP_TimerExpired);
  MESSAGE_InfoAlloc(node, timeoutMsg, sizeof(AppTimer));
  info = (AppTimer *) MESSAGE_ReturnInfo(timeoutMsg);
  info->connectionId = (uint64_t)ccnMsg->msg_full_name;
  info->sourcePort = APP_CCN_LISTEN_PORT;
  info->type = APP_TIMER_RE_SEND_PKT;
  
  map<uint64_t, Message*>::iterator it_msg;
  CcnMsgBufferMap_t::iterator it_ccnMsg;

  it_msg = this->cancel_reTransMsg_map.find(ccnMsg->msg_full_name);
  it_ccnMsg = this->reTrans_ccnMsgBuffer.find(ccnMsg->msg_full_name);

  if(it_msg != this->cancel_reTransMsg_map.end()) {
    printf("[node:%d]msg_full_name: %lu\n", node->nodeId, ccnMsg->msg_full_name);
    printf("[node%d][msg%lu] %d %d\n",node->nodeId, ccnMsg->msg_full_name, ccnMsg->msg_name, ccnMsg->msg_chunk_num);
    ERROR_ReportError("Unexpected data in cacnel_reTransMsg_map\n");
  }
  if(it_ccnMsg != this->reTrans_ccnMsgBuffer.end()) {
    printf("[node:%d]msg_full_name: %lu\n", node->nodeId, ccnMsg->msg_full_name);
    ERROR_ReportError("Unexpected data in reTrans_ccnMsgBuffer\n");
  }
  
  this->cancel_reTransMsg_map.insert(pair<uint64_t, Message*>(ccnMsg->msg_full_name, timeoutMsg));
  this->reTrans_ccnMsgBuffer.insert(pair<uint64_t, CcnMsg*>(ccnMsg->msg_full_name, this->NewCcnMsg(ccnMsg)));
  MESSAGE_Send(node, timeoutMsg, 2 * SECOND);
}
Пример #2
0
void BrpProcessEvent(Node* node, Message* msg)
{
    IerpData* ierpData = (IerpData*) IerpGetRoutingProtocol(
                            node,
                            ROUTING_PROTOCOL_IERP);

    BrpData* brpData = (BrpData*) ierpData->brpData;

    // Fuction to process timers
    switch (MESSAGE_GetEvent(msg))
    {
        case MSG_NETWORK_BrpDeleteQueryEntry:
        {
            unsigned int* brpCacheId
                            = (unsigned int*) MESSAGE_ReturnInfo(msg);

            BrpDeleteQueryCoverageEntryByCacheId(brpData, *brpCacheId);

            break;
        }
        default:
        {
            ERROR_Assert(FALSE, "Delete query is the only event now");
        }
    }
}
Пример #3
0
/*
 * NAME:        ZigbeeAppClientScheduleNextPkt.
 * PURPOSE:     schedule the next packet the client will send.  If next packet
 *              won't arrive until the finish deadline, schedule a close.
 * PARAMETERS:  node - pointer to the node,
 *              clientPtr - pointer to the zigbeeApp client data structure.
 * RETRUN:      none.
 */
void
ZigbeeAppClientScheduleNextPkt(Node* node, AppDataZigbeeappClient* clientPtr)
{
    AppTimer* timer = NULL;
    Message* timerMsg = NULL;

    timerMsg = MESSAGE_Alloc(node,
                             APP_LAYER,
                             APP_ZIGBEEAPP_CLIENT,
                             MSG_APP_TimerExpired);

    MESSAGE_InfoAlloc(node, timerMsg, sizeof(AppTimer));

    timer = (AppTimer*) MESSAGE_ReturnInfo(timerMsg);
    timer->sourcePort = clientPtr->sourcePort;
    timer->type = APP_TIMER_SEND_PKT;

#ifdef DEBUG
    {
        char clockStr[24];
        printf("ZIGBEEAPP Client: Node %u scheduling next data packet\n",
               node->nodeId);
        printf("    timer type is %d\n", timer->type);
        TIME_PrintClockInSecond(clientPtr->interval, clockStr);
        printf("    interval is %sS\n", clockStr);
    }
#endif /* DEBUG */

    MESSAGE_Send(node, timerMsg, clientPtr->interval);
}
Пример #4
0
//-------------------------------------------------------------------------
// FUNCTION     : NdpSetHoldTimerForTheNeighbor()
//
// PURPOSE      : This function sets a hold timer for a given neighbor
//
// PARAMETERS   : node - node which is setting the hold timer.
//                ndpData - pointer to NdpData
//                neighborInfo - neighbor for which hold timer is to be set.
//
// RETURN VALUE : None
//-------------------------------------------------------------------------
static
void NdpSetHoldTimerForTheNeighbor(
    Node* node,
    NdpData* ndpData,
    NdpNeighborStruct* neighborInfo)
{

    clocktype delay = (ndpData->numHelloLossAllowed
        + neighborInfo->neighborHelloInterval) * SECOND;

    if (neighborInfo->neighborHelloInterval > 0)
    {
        Message* msg = MESSAGE_Alloc(
                           node,
                           NETWORK_LAYER,
                           NETWORK_PROTOCOL_NDP,
                           NETWORK_NdpHoldTimerExpired);

        MESSAGE_InfoAlloc(node, msg, sizeof(NdpNeighborStruct));

        memcpy(MESSAGE_ReturnInfo(msg), neighborInfo,
            sizeof(NdpNeighborStruct));

        MESSAGE_Send(node, msg, delay);
    }
}
Пример #5
0
STAT_Timing* STAT_GetTiming(Node* node, Message* message)
{
    STAT_Timing* timing = (STAT_Timing*) MESSAGE_ReturnInfo(message, INFO_TYPE_StatsTiming);
    if (timing == NULL)
    {
        MESSAGE_AddInfo(
            node,
            message,
            sizeof(STAT_Timing),
            INFO_TYPE_StatsTiming);
        timing = (STAT_Timing*) MESSAGE_ReturnInfo(
            message,
            INFO_TYPE_StatsTiming);
        timing->Initialize();
    }

    return timing;
}
Пример #6
0
CcnMsg* NodeData::BufferRetrieve_Client(Node* node, Message* msg) {
  TransportToAppOpenResult* openResult;
  openResult = (TransportToAppOpenResult*) MESSAGE_ReturnInfo(msg);

  CcnMsgBufferMap_t::iterator it;
  it = this->ccnMsgBuffer.find(openResult->uniqueId);

  if(it == this->ccnMsgBuffer.end()) {
    ERROR_ReportError("node open unexist msg from ccnMsgBuffer\n");
  }

  CcnMsg* ccnMsg;
  ccnMsg = it->second;
  this->ccnMsgBuffer.erase(it);

  return ccnMsg;
}
Пример #7
0
static
void BrpScheduleDelete(Node* node, unsigned int brpCacheId)
{
    unsigned int* info;

    Message* newMsg = MESSAGE_Alloc(
        node,
        NETWORK_LAYER,
        ROUTING_PROTOCOL_BRP,
        MSG_NETWORK_BrpDeleteQueryEntry);

    MESSAGE_InfoAlloc(
        node,
        newMsg,
        sizeof(unsigned int));

    info = (unsigned int *) MESSAGE_ReturnInfo(newMsg);
    *info = brpCacheId;

    // Schedule the timer after the specified delay
    MESSAGE_Send(node, newMsg, BRP_DEFAULT_REQUEST_TIMEOUT);
}
Пример #8
0
Файл: ccn.cpp Проект: LXiong/ccn
void AppLayerCCNHost(Node* node, Message* msg) {
  NodeData* nodeData;
  nodeData = (NodeData*)node->appData.nodeData;

  switch(msg->eventType) 
  {
  /*//fujiwara//
   * 1. 移動を検知したらMR(interest)を作成してPoAとHOMEにおくる
   * 2. MR(data)を受け取ったら
   * 		さらに分岐
  case hand_over_kenchi //やることを書く
  {
      clocktype send_delayTime;
          uint32_t chunk_num;
          map<uint32_t, clocktype>::iterator it;
          uint32_t next_msgName = global_node_data->return_MsgName();
          uint32_t end_chunk_num = next_msgName % 40 + 10;

          CcnMsg* ccnMsg;
            ccnMsg = new CcnMsg();
            ccnMsg->resent_times = 0;
            ccnMsg->ccn_method = DEFAULT;
            ccnMsg->msg_type = Interest;
            ccnMsg->msg_name = next_msgName; //msg_nameはよくわからない 多分解析のときにわかりやすくする狙いか?
            ccnMsg->msg_chunk_num = nodeData->return_lastChunkNum(ccnMsg) + 1;
            ccnMsg->EncodeFullNameMsg();
            ccnMsg->sender_node_id = node->nodeId;    // node->nodeid = このメッセージを送るノードのID
            ccnMsg->source_node_id = source_node_id;  //ここを変更 source_node_id = 送信先ノード(現状サーバが一個しかとれない仕様……)
            ccnMsg->payload_length = 30; //ペイロードはヘッダを除いたデータ部分の大きさ
            ccnMsg->hops_limit = 20;
            ccnMsg->content_type = CommonData;
            ccnMsg->end_chunk_num = end_chunk_num;
            ccnMsg->interest_genTime = node->getNodeTime();
            ccnMsg->data_genTime     = node->getNodeTime();

            nodeData->set_lastChunkNum(ccnMsg); //chunkの最後の値を記録 よくわからない 必要?
            nodeData->reqMapInput(node, ccnMsg); //msg_full_nameとノードのシミュレーション時間のペアを記録する
            nodeData->fibSend_DEFAULT(node, ccnMsg);//送信
            nodeData->make_reTransMsg(node, ccnMsg);//再送の話 よくわからない 必要か?
  }*/
    case MSG_APP_FromTransDataReceived: // データ受け取り時
    {
      TransportToAppDataReceived *openResult;
      openResult = (TransportToAppDataReceived*) MESSAGE_ReturnInfo(msg);
      APP_TcpCloseConnection(node, openResult->connectionId);

      // msgからccnメッセージを取得
      // ccnメッセージを処理
      // データ送信の場合、TCP接続要求を送る

      // msgのキーからccnメッセージを取り出す
      CcnMsg* ccnMsg;
      ccnMsg = nodeData->BufferRetrieve_Host(node, msg);

      Node* remote_node;
      NodeData* remote_nodeData;

      remote_node = MAPPING_GetNodePtrFromHash(GlobalNodeData::nodeHash, ccnMsg->previous_node_id);
      remote_nodeData = (NodeData*)remote_node->appData.nodeData;

      // パケットロストによる取得エラー
      if(nodeData->node_role + remote_nodeData->node_role == CLIENT + RELAY_NODE) {
        if((rand() * 100.0) < (nodeData->error_rate * RAND_MAX)) {
          //printf("packet lost occured at %d->%d\n", remote_node->nodeId, node->nodeId);
          //nodeData->statData->packet_lostTimes++;
          if(ccnMsg->ccn_method == PROPOSAL && 
              (ccnMsg->msg_type == Interest || ccnMsg->msg_type == Data)){
          } else if(ccnMsg->ccn_method == PRIOR) {
            nodeData->statData->packet_lostTimes++;  // this is not lost but unacquired
            break;
          } else {
            break;
          }
        }
      }

      nodeData->StatisticalInfo_recvCcnMsg(node, ccnMsg);

      // ホップカウント(loop検出用)
      if(!ccnMsg->checkHopCount()) {
        printf("hop count is over\n");
        break;
      }

      switch(ccnMsg->ccn_method) 
      {

        case DEFAULT:
        case DEFAULT_FAST:
        {
          switch(ccnMsg->msg_type) {
            case Interest:
            {
              // ソースノードまで転送
              // PITに名前を記録(msg_full_name)
              // ソースノードならDataパケットを返送
              // 返送する際はPITを参照
              
              if(nodeData->pitInsert_DEFAULT(node, ccnMsg)) {
                // PITで登録済み
                delete ccnMsg;
                break;
              }

              if(nodeData->csSend(node, ccnMsg) == true) {
                // キャッシュヒット
                if(ccnMsg->content_type == CommonData) {
                  nodeData->StatisticalInfo_cacheHit(node, ccnMsg);
                }
                break;
              }

              // ソースノード到着
              if(ccnMsg->source_node_id == node->nodeId) {
                // InterestをDataに変換
                nodeData->convertInterest_intoData(ccnMsg);

                // Dataの送信時間設定
                clocktype send_delayTime;

                if(ccnMsg->content_type == VideoData) {
                  map<uint32_t, clocktype>::iterator it;
                  it = nodeData->dataGenerateTime_map.find(ccnMsg->msg_chunk_num);
                  send_delayTime = it->second - node->getNodeTime();
                } else {
                  send_delayTime = 0;
                }

                // PITで設定時間に則った送信
                if(send_delayTime < 0) {
                  nodeData->pitSend_DEFAULT(node, ccnMsg);
                } else {
                  nodeData->pitSend_DEFAULT(node, ccnMsg, send_delayTime);
                }
              }
              else {
                // FIBによるフォワーディング
                nodeData->fibSend_DEFAULT(node, ccnMsg);
              }
              break;
            } // Interest

            case Data:
            {
              //if(ccnMsg->content_type == CommonData) {
              //  nodeData->statData->commonPacket_recv++;
              //  nodeData->statData->commonPacketSize_recv += ccnMsg->payload_length;
              //} else if(ccnMsg->content_type == VideoData) {
              //  nodeData->statData->videoPacket_recv++;
              //  nodeData->statData->videoPacketSize_recv += ccnMsg->payload_length;
              //}

              if(nodeData->reqMapSearch(node, ccnMsg)) {
                if(ccnMsg->content_type == CommonData) {
                  nodeData->statData->request_commonPacket_recv++;
                  nodeData->statData->request_commonPacketSize_recv += ccnMsg->payload_length;
                } else if(ccnMsg->content_type == VideoData) {
                  nodeData->statData->request_videoPacket_recv++;
                  nodeData->statData->request_videoPacketSize_recv += ccnMsg->payload_length;
                }
                
                // PROPOSAL再送での誤爆回避
                if(nodeData->ccn_method == PROPOSAL) {
                  if(ccnMsg->content_type == VideoData) {
                    nodeData->Cancel_reTransMsg(node, ccnMsg->msg_full_name);
                    nodeData->recvRequestData(node, ccnMsg);  // Statistical data 
                    delete ccnMsg;
                    break;  
                  }
                }

                // 再送パケットは次のパケットを要求しないため、ここで終了
                if(ccnMsg->resent_times > 0) {
                  if(ccnMsg->content_type == VideoData) {
                    if(nodeData->ccn_method == DEFAULT) {
                      nodeData->Cancel_reTransMsg(node, ccnMsg->msg_full_name);
                      nodeData->recvRequestData(node, ccnMsg);  // Statistical data 
                      delete ccnMsg;
                      break;
                    }
                    else if(nodeData->ccn_method == DEFAULT_FAST) {
                      nodeData->Cancel_reTransMsg(node, ccnMsg->msg_full_name);
                      nodeData->recvRequestData(node, ccnMsg);  // Statistical data 
                      delete ccnMsg;
                      break;
                    }
                  }
                }
                // 未取得chunkを取得
                if(nodeData->ccn_method == DEFAULT_FAST) {
                  if(ccnMsg->content_type == VideoData) {
                    if(ccnMsg->msg_chunk_num > nodeData->return_lastRecvMsg(ccnMsg) + 1) {

                      CcnMsg* t_ccnMsg;
                      t_ccnMsg = nodeData->NewCcnMsg(ccnMsg);
                      t_ccnMsg->msg_chunk_num = nodeData->return_lastRecvMsg(ccnMsg) + 1;
                      t_ccnMsg->EncodeFullNameMsg();
                      t_ccnMsg->payload_length = 30;
                      t_ccnMsg->resent_times = 1;
                      t_ccnMsg->msg_type = Interest;
                      t_ccnMsg->hops_limit = 20;

                      nodeData->reqMapSearch(node, t_ccnMsg);
                      nodeData->reqMapInput(node, t_ccnMsg);

                      nodeData->Cancel_reTransMsg(node, t_ccnMsg->msg_full_name);
                      nodeData->make_reTransMsg(node, t_ccnMsg);

                      Node* source_node;
                      map<uint32_t, clocktype>::iterator it;
                      source_node = MAPPING_GetNodePtrFromHash(GlobalNodeData::nodeHash, source_node_id);
                      nodeData->source_nodeData = (NodeData*)source_node->appData.nodeData;
                      NodeData* source_nodeData;
                      source_nodeData = nodeData->source_nodeData;

                      it = source_nodeData->dataGenerateTime_map.find(t_ccnMsg->msg_chunk_num);
                      t_ccnMsg->data_genTime = it->second;

                      nodeData->set_windowSize(node, t_ccnMsg);
                      nodeData->fibSend(node, t_ccnMsg);
                    }
                  }
                }
                nodeData->release_windowSize(node, ccnMsg);

                nodeData->set_lastRecvMsg(ccnMsg);
                nodeData->Cancel_reTransMsg(node, ccnMsg->msg_full_name);
                nodeData->recvRequestData(node, ccnMsg);  // Statistical data 

                if(ccnMsg->end_chunk_num < nodeData->return_lastChunkNum(ccnMsg) + 1) {
                  delete ccnMsg;
                  break;
                }


                // クライアントにData到着
                ccnMsg->msg_type = Interest;
                ccnMsg->msg_chunk_num = nodeData->return_lastChunkNum(ccnMsg) + 1;
                ccnMsg->EncodeFullNameMsg();
                ccnMsg->resent_times = 0;
                ccnMsg->payload_length = 30;
                ccnMsg->hops_limit = 20;
                ccnMsg->interest_genTime = node->getNodeTime();

                map<uint32_t, clocktype>::iterator it;
                it = nodeData->source_nodeData->dataGenerateTime_map.find(ccnMsg->msg_chunk_num);
                ccnMsg->data_genTime = it->second;

                nodeData->set_lastChunkNum(ccnMsg);
                nodeData->set_windowSize(node, ccnMsg);
                nodeData->make_reTransMsg(node, ccnMsg);
                nodeData->reqMapInput(node, ccnMsg);
                nodeData->fibSend(node, ccnMsg);

                break;
              }
              nodeData->csInsert_DEFAULT(node, ccnMsg);
              nodeData->pitSend_DEFAULT(node, ccnMsg);
              break;
            }

            default:
            {
              ERROR_ReportError("Undefined msg type\n");
            }
          }
          break;
        }

        case PRIOR:
        {
          switch(ccnMsg->msg_type) {
            case Interest:
            {
              // ソースノードまで転送
              // PITに名前を記録(msg_name)
              // ソースノードならDataパケットを返送
              // またDataパケットを一定時間ごとに生成・転送
              // 返送する際はPITを参照
              if(nodeData->csSend(node, ccnMsg) == true) {
                // キャッシュヒット
                nodeData->StatisticalInfo_cacheHit(node, ccnMsg);
                break;
              }

              if(nodeData->pitInsert_PRIOR(node, ccnMsg)) {
                // PITで登録済み
                delete ccnMsg;
                break;
              }

              if(ccnMsg->source_node_id == node->nodeId) {
                nodeData->convertInterest_intoData(ccnMsg);
                nodeData->set_lastChunkNum(ccnMsg);
                APP_SetTimer(node, APP_CCN_CLIENT, 0, APP_CCN_LISTEN_PORT, APP_TIMER_DATA_SEND_PKT, 0 * MILLI_SECOND);
              }
              else {
                nodeData->fibSend_PRIOR(node, ccnMsg);
              }

              break;
            }

            case Data:
            {
              if(nodeData->reqMapSearch_PRIOR(node, ccnMsg)) {
                nodeData->recvRequestData(node, ccnMsg);  // Statistical data 
                delete ccnMsg;
                break;
              }
              nodeData->pitSend_PRIOR(node, ccnMsg);
              break;
            }

            default:
              ERROR_ReportError("Undefined msg type\n");
          }
          break;
        }

        case PROPOSAL:
        {
          switch(ccnMsg->msg_type) {
            case Interest:
            {
              nodeData->fibModInsert(node, ccnMsg, ccnMsg->previous_node_id);
              if(nodeData->pitInsert_PROPOSAL(node, ccnMsg)) {
                // PITで登録済み
                delete ccnMsg;
                break;
              }

              if(ccnMsg->source_node_id == node->nodeId) {
                nodeData->set_lastChunkNum(ccnMsg);
                nodeData->convertInterest_intoData(ccnMsg);
                nodeData->pitSend_PROPOSAL(node, ccnMsg);
                // プッシュ配信登録
                APP_SetTimer(node, APP_CCN_CLIENT, 0, APP_CCN_LISTEN_PORT, APP_TIMER_fakeINTEREST_SEND_PKT, 0 * MILLI_SECOND);
              }
              else {
                nodeData->fibSend_PROPOSAL(node, ccnMsg);
              }
              break;
            }

            case Data:
            {
              if(nodeData->reqMapSearch(node, ccnMsg)) {
                nodeData->recvRequestData(node, ccnMsg);  // Statistical data 

                // プッシュ配信登録済みクライアントであることを記録
                nodeData->reqModMapInput(node, ccnMsg);
                delete ccnMsg;
                break;
              }
              nodeData->pitSend_PROPOSAL(node, ccnMsg);

              break;
            }

            case fakeInterest:
            {
              nodeData->pitModInsert(node, ccnMsg);
              nodeData->csModInsert(node, ccnMsg);
if(nodeData->node_role == CLIENT)
if(ccnMsg->msg_name != msg_videoData_name + node->nodeId%3)
    printf("[node%d][msg%lu] fuckfuckfuck %d %d\n",node->nodeId, ccnMsg->msg_full_name, ccnMsg->msg_name, ccnMsg->msg_chunk_num);

              if(nodeData->reqModMapSearch(node, ccnMsg)) { // クライアント到着
                nodeData->recvRequestData(node, ccnMsg);  // Statistical data 
                nodeData->recvModMapInsert(node, ccnMsg);

                nodeData->convertFakeInterest_intoFakeData(ccnMsg);
                nodeData->pitModSend(node, ccnMsg);

                // 未取得chunkを取得
                if(ccnMsg->msg_chunk_num > nodeData->return_lastRecvMsg(ccnMsg) + 1) {
                  CcnMsg* ccnMsg;
                  ccnMsg = new CcnMsg();
                  ccnMsg->resent_times = 1;
                  ccnMsg->ccn_method = DEFAULT;
                  ccnMsg->msg_type = Interest;
                  ccnMsg->msg_name = msg_videoData_name + node->nodeId % 3;
                  ccnMsg->msg_chunk_num = nodeData->return_lastRecvMsg(ccnMsg) + 1;
                  ccnMsg->EncodeFullNameMsg();
                  ccnMsg->sender_node_id = node->nodeId;
                  ccnMsg->source_node_id = source_node_id;
                  ccnMsg->payload_length = 30;
                  ccnMsg->hops_limit = 20;
                  ccnMsg->interest_genTime = node->getNodeTime();
                  ccnMsg->content_type = VideoData;
                  ccnMsg->end_chunk_num = UINT16_MAX;

                  Node* source_node;
                  map<uint32_t, clocktype>::iterator it;
                  source_node = MAPPING_GetNodePtrFromHash(GlobalNodeData::nodeHash, source_node_id);
                  nodeData->source_nodeData = (NodeData*)source_node->appData.nodeData;
                  NodeData* source_nodeData;
                  source_nodeData = nodeData->source_nodeData;

                  it = source_nodeData->dataGenerateTime_map.find(ccnMsg->msg_chunk_num);
                  ccnMsg->data_genTime = it->second;

                  nodeData->reqMapSearch(node, ccnMsg);
                  nodeData->set_windowSize(node, ccnMsg);
                  nodeData->reqMapInput(node, ccnMsg);
                  nodeData->make_reTransMsg(node, ccnMsg);
                  nodeData->fibSend(node, ccnMsg);
                } else if (ccnMsg->msg_chunk_num == nodeData->return_lastRecvMsg(ccnMsg) + 1){
                  //printf("Got actual packet\n");
                } else {
                }
                nodeData->set_lastRecvMsg(ccnMsg);
                break;
              }


              if(nodeData->fibModSend(node, ccnMsg)) {
                delete ccnMsg;
                break;
              }
              break;
            }

            case fakeData:
            {
              // クライアントにデータ到着
              if(ccnMsg->source_node_id == node->nodeId) {
                delete ccnMsg;
                break;
              }

              nodeData->pitModSend(node, ccnMsg);
              break;
            }

            default:
              ERROR_ReportError("Undefined msg type\n");
          }
          break;
        }

        default:
          ERROR_ReportError("Undefined ccn_method\n");
      }
      break;
    }

    case MSG_APP_FromTransOpenResult:   // TCPでpassive open処理が終了
      //if(node->nodeId == 1) printf("openResult->connectionId: %lu\n", openResult->connectionId);
      break;
    case MSG_APP_FromTransListenResult: // コネクション要求待機状態を確立
      //if(node->nodeId == 1) printf("openResult->connectionId: %lu\n", openResult->connectionId);
      break;

    case MSG_APP_TimerExpired: 
    {  
      AppTimer* timer;
      timer = (AppTimer *)MESSAGE_ReturnInfo(msg);
      switch(timer->type) {
        case APP_TIMER_RE_SEND_PKT:
          nodeData->send_reTransMsg(node, timer->connectionId);
        break;
      }
      break;
    }
    case MSG_APP_FromTransCloseResult:
      break;
    default:
      printf("msg->eventType = %d\n", msg->eventType);
      ERROR_ReportError("msg->eventType error: undefined eventType\n");
  }
  MESSAGE_Free(node, msg);
}
Пример #9
0
Файл: ccn.cpp Проект: LXiong/ccn
void AppLayerCCNClient(Node* node, Message* msg) {
  NodeData* nodeData;
  nodeData = (NodeData*)node->appData.nodeData;

  Node* source_node;
  source_node = MAPPING_GetNodePtrFromHash(GlobalNodeData::nodeHash, source_node_id);
  nodeData->source_nodeData = (NodeData*)source_node->appData.nodeData;
  NodeData* source_nodeData;
  source_nodeData = nodeData->source_nodeData;

  switch(msg->eventType) 
  {
    // タイマーメッセージ
    case MSG_APP_TimerExpired:        // タイマーメッセージ
    {
      AppTimer* timer;
      timer = (AppTimer *)MESSAGE_ReturnInfo(msg);

      // timer messageの種類によって処理を分ける
      switch(timer->type) 
      {
        case APP_TIMER_SEND_PKT:
        {
            printf("この表示がなければ、APP_TIMER_SEND_PKTはビデオストリーミング確定 ");

          clocktype send_delayTime;
          uint32_t chunk_num;
          map<uint32_t, clocktype>::iterator it;

          chunk_num = 0;
          do {
            chunk_num++; 
            it = source_nodeData->dataGenerateTime_map.find(chunk_num);
            if(it == source_nodeData->dataGenerateTime_map.end()) {
              ERROR_ReportError("dataGenerateTime_map error\n");
            }
            send_delayTime = it->second - node->getNodeTime();
          } while(send_delayTime < 0);
          nodeData->set_lastChunkNum(msg_videoData_name + node->nodeId % 3, chunk_num - 1);
          nodeData->set_lastRecvMsg(msg_videoData_name + node->nodeId % 3, chunk_num - 1);

          CcnMsg* ccnMsg;
          do {
            ccnMsg = new CcnMsg();
            ccnMsg->ccn_method = nodeData->ccn_method;
            ccnMsg->resent_times = 0;
            ccnMsg->msg_type = Interest;
            ccnMsg->msg_name = msg_videoData_name + node->nodeId % 3;
            ccnMsg->msg_chunk_num = nodeData->return_lastChunkNum(ccnMsg) + 1;
            ccnMsg->EncodeFullNameMsg();
            ccnMsg->sender_node_id = node->nodeId;
            ccnMsg->source_node_id = source_node_id;
            ccnMsg->payload_length = 30;
            ccnMsg->hops_limit = 20;
            ccnMsg->interest_genTime = node->getNodeTime();
            ccnMsg->content_type = VideoData;
            ccnMsg->end_chunk_num = UINT32_MAX;

            it = source_nodeData->dataGenerateTime_map.find(ccnMsg->msg_chunk_num);
            ccnMsg->data_genTime = it->second;

            nodeData->set_lastChunkNum(ccnMsg);
            nodeData->fibSend(node, ccnMsg);
            if(ccnMsg->ccn_method == DEFAULT) {
              nodeData->make_reTransMsg(node, ccnMsg);
              nodeData->set_lastRecvMsg(msg_videoData_name + node->nodeId % 3, UINT32_MAX - 3);
              nodeData->reqMapInput(node, ccnMsg);
            }
            else if(ccnMsg->ccn_method == DEFAULT_FAST) {
              nodeData->make_reTransMsg(node, ccnMsg);
              nodeData->set_lastRecvMsg(msg_videoData_name + node->nodeId % 3, UINT32_MAX - 3);
              nodeData->reqMapInput(node, ccnMsg);
            }
            else if(ccnMsg->ccn_method == PRIOR) {
              nodeData->reqMapInput_PRIOR(node, ccnMsg);
              break;
            }
            else if(ccnMsg->ccn_method == PROPOSAL) {
              nodeData->set_lastRecvMsg(msg_videoData_name + node->nodeId % 3, UINT32_MAX - 1);
              nodeData->reqMapInput(node, ccnMsg);
              //printf("[node%d][msg%d] sendInterest\n", node->nodeId, ccnMsg->msg_name);
              break;
            }
          } while(nodeData->set_windowSize(node, ccnMsg));
          break;
        }  // APP_TIMER_SEND_PKT
        
        case APP_TIMER_DATA_SEND_PKT:
        {
            printf("この表示がなければ、APP_TIMER_DATA_SEND_PKTはいらない子。てかどうやってここはいるんだ… ");

          CcnMsg* ccnMsg;
          for(int i = 0; i < 3; i++) {
            ccnMsg = new CcnMsg();
            ccnMsg->resent_times = 0;
            ccnMsg->ccn_method = PRIOR;
            ccnMsg->msg_type = Data;
            ccnMsg->msg_name = msg_videoData_name + i;
            ccnMsg->msg_chunk_num = nodeData->return_lastChunkNum(ccnMsg) + 1;
            ccnMsg->EncodeFullNameMsg();
            ccnMsg->sender_node_id = node->nodeId;
            ccnMsg->source_node_id = source_node_id;
            ccnMsg->payload_length = nodeData->tcp_mss;
            ccnMsg->hops_limit = 20;
            ccnMsg->interest_genTime = node->getNodeTime();
            ccnMsg->content_type = VideoData;
            ccnMsg->end_chunk_num = UINT32_MAX;
            
            map<uint32_t, clocktype>::iterator it;
            it = nodeData->dataGenerateTime_map.find(ccnMsg->msg_chunk_num);
            ccnMsg->data_genTime = it->second;
    
            clocktype send_delayTime;
            send_delayTime = ccnMsg->data_genTime - node->getNodeTime();
            if(send_delayTime < 0) send_delayTime = 0;

            nodeData->set_lastChunkNum(ccnMsg);
            nodeData->pitSend_PRIOR(node, nodeData->NewCcnMsg(ccnMsg), send_delayTime);
            APP_SetTimer(node, APP_CCN_CLIENT, 0, APP_CCN_LISTEN_PORT, APP_TIMER_DATA_SEND_PKT, send_delayTime);
          }
          delete ccnMsg;
          break;
        }  // APP_TIMER_DATA_SEND_PKT

        case APP_TIMER_fakeINTEREST_SEND_PKT:
        {
            printf("この表示がなければ、APP_TIMER_fakeINTEREST_SEND_PKTはいらない子。てかここどうやって入るんだ… ");

          // 動画の配信分をすべて出す
          CcnMsg* ccnMsg;
          for(int i = 0; i < 3; i++) {
            ccnMsg = new CcnMsg();
            ccnMsg->resent_times = 0;
            ccnMsg->ccn_method = PROPOSAL;
            ccnMsg->msg_type = fakeInterest;
            ccnMsg->msg_name = msg_videoData_name + i;
            ccnMsg->msg_chunk_num = nodeData->return_lastChunkNum(ccnMsg) + 1;
            ccnMsg->EncodeFullNameMsg();
            ccnMsg->sender_node_id = node->nodeId;
            ccnMsg->source_node_id = source_node_id;
            ccnMsg->payload_length = nodeData->tcp_mss;
            ccnMsg->hops_limit = 20;
            ccnMsg->interest_genTime = node->getNodeTime();
            ccnMsg->content_type = VideoData;
            ccnMsg->end_chunk_num = UINT32_MAX;
            
            map<uint32_t, clocktype>::iterator it;
            it = nodeData->dataGenerateTime_map.find(ccnMsg->msg_chunk_num);
            ccnMsg->data_genTime = it->second;

            clocktype send_delayTime;
            send_delayTime = ccnMsg->data_genTime - node->getNodeTime();
            if(send_delayTime < 0) send_delayTime = 0;

            nodeData->set_lastChunkNum(ccnMsg);
            nodeData->fibModSend(node, nodeData->NewCcnMsg(ccnMsg), send_delayTime);
            APP_SetTimer(node, APP_CCN_CLIENT, 0, APP_CCN_LISTEN_PORT, APP_TIMER_fakeINTEREST_SEND_PKT, send_delayTime);
          }
          delete ccnMsg;
          break;
        }  // APP_TIMER_fakeINTEREST_SEND_PKT

        case APP_TIMER_REGULAR_SEND_PKT:
        {
            //printf("この表示は 予想ではたくさんでる。APP_TIMER_REGULAR_SEND_PKT\n");
          clocktype send_delayTime;
          uint32_t chunk_num;
          map<uint32_t, clocktype>::iterator it;
          uint32_t next_msgName = global_node_data->return_MsgName();
          uint32_t end_chunk_num = next_msgName % 40 + 10;

          CcnMsg* ccnMsg;
          do {
            ccnMsg = new CcnMsg();
            ccnMsg->resent_times = 0;
            ccnMsg->ccn_method = DEFAULT;
            ccnMsg->msg_type = Interest;
            ccnMsg->msg_name = next_msgName;
            ccnMsg->msg_chunk_num = nodeData->return_lastChunkNum(ccnMsg) + 1;
            ccnMsg->EncodeFullNameMsg();
            ccnMsg->sender_node_id = node->nodeId;
            ccnMsg->source_node_id = source_node_id;
            ccnMsg->payload_length = 30;
            ccnMsg->hops_limit = 20;
            ccnMsg->content_type = CommonData;
            ccnMsg->end_chunk_num = end_chunk_num;
            ccnMsg->interest_genTime = node->getNodeTime();
            ccnMsg->data_genTime     = node->getNodeTime();

            nodeData->set_lastChunkNum(ccnMsg);
            nodeData->reqMapInput(node, ccnMsg);
            nodeData->fibSend_DEFAULT(node, ccnMsg);
            nodeData->make_reTransMsg(node, ccnMsg);

            if(ccnMsg->msg_chunk_num > ccnMsg->end_chunk_num) break;
          } while(nodeData->set_windowSize(node, ccnMsg));

          APP_SetTimer(node, APP_CCN_CLIENT, 0, APP_CCN_LISTEN_PORT, APP_TIMER_REGULAR_SEND_PKT, nodeData->commonPacketGenerateTime);

          break;
        } // APP_TIMER_REGULAR_SEND_PKT

        default:
          ERROR_ReportError("Undefined timer type\n");
      }
      break;
    } // MSG_APP_TimerExpired

    case MSG_APP_FromTransOpenResult:  // TCPでactive open処理が完了
    {
      // データ送信処理 
      // 送信データの操作は出来る限りHostの処理にしておく
      // ここでは送信処理だけ
      TransportToAppOpenResult *openResult;
      openResult = (TransportToAppOpenResult*) MESSAGE_ReturnInfo(msg);

      //TCPコネクションが不成立時(失敗)
      if (openResult->connectionId < 0)
      {
        char buf[MAX_STRING_LENGTH];
        ctoa(node->getNodeTime(),buf);
        node->appData.numAppTcpFailure++;
        break;
      }

      // バッファーからccnメッセージを取り出し
      CcnMsg* ccnMsg;
      ccnMsg = nodeData->BufferRetrieve_Client(node, msg);

      nodeData->StatisticalInfo_sendCcnMsg(node, ccnMsg);

      ccnMsg->App_TcpSendCcnMsg(node, msg);
      break;
    } // MSG_APP_FromTransOpenResult

    case MSG_APP_FromTransDataSent:    // TCPでデータ転送終了
      TransportToAppDataSent *openResult;
      openResult = (TransportToAppDataSent*) MESSAGE_ReturnInfo(msg);

      APP_TcpCloseConnection(node, openResult->connectionId);
      break;

    case MSG_APP_FromTransCloseResult:
      break;
    default:
      ERROR_ReportError("msg->eventType error: undefined eventType\n");
  }
  MESSAGE_Free(node, msg);
}
/*
 * Protocol routing function.
 */
void DearRouterFunction(Node* node, Message* msg, NodeAddress destAddr, NodeAddress previousHopAddress, BOOL* packetWasRouted) {
 double ratio = 1.0e+299;
 NodeAddress nextHop = 0;
 NodeAddress *nextHopInfoPtr = (NodeAddress *)MESSAGE_ReturnInfo(msg, INFO_TYPE_DearNextHop);
 IpHeaderType* ipHeader = (IpHeaderType*)msg->packet;
   
 // Obtain a pointer to the local variable space.
 DearData* dear = (DearData*)NetworkIpGetRoutingProtocol(node, ROUTING_PROTOCOL_DEAR);
 assert(dear != NULL);
  
 // Do not route any packets destined to self.
 if (MAPPING_GetNodeIdFromInterfaceAddress(node, destAddr) == node->nodeId) {
  // Remove the next hop info field if present.
  if (nextHopInfoPtr != NULL)
   MESSAGE_RemoveInfo(node, msg, INFO_TYPE_DearNextHop);
  return;
 }
 
 // Do not route the packet if we are not the next hop for this packet.
 if (nextHopInfoPtr != NULL && *nextHopInfoPtr != node->nodeId)
  return;
 
 // Find the best neighbour to route packet to.
 for (int i = 1; i <= node->numNodes; i++) {
  // Skip non-neighbours.
  if (!dear->neighbours[i].valid)
   continue;
  
  // Skip the degenerate case where destination sends to destination.
  if (i == dear->destination)
   continue;
   
  // Get the candidate node.
  Node *candidate = DearGetNodeById(node, i);
  
  // Read the battery level of the candidate.
  double battery = DearGetRemainingBatteryPercent(candidate, dear->neighbours[i].battery_max);
  
  // Make sure the node isn't dead.
  if (battery <= 0.0)
   continue;
   
  // Calculate the power in mW.
  double power_mW = pow(10.0, dear->neighbours[i].power / 10.0);
  
  // Calculate the metric.
  double metric = power_mW / battery;
  
  if (candidate->nodeId != node->nodeId) {
   // INDIRECT TRANSMISSION: Add the default transmission power to neighbour.
   battery = DearGetRemainingBatteryPercent(node, dear->neighbours[node->nodeId].battery_max);
   
   if (battery <= 0.0)
    continue; // This can only happen if the originating node is dead.
   
   // Calculate the power in mW.
   power_mW = pow(10.0, dear->defaultPower / 10.0);
   
   // Adjust the metric. 
   metric += power_mW / battery;
  }
  
  // Check if calculated metric is lower than the lowest metric so far.
  if (metric < ratio) {
   nextHop = i;
   ratio = metric;
  }
 }
 
 // Set the real destination if needed (when next hop is current node,
 // the real next hop is the final destination).
 if (nextHop == node->nodeId)
  nextHop = dear->destination;
 
 // Route the packet only when the destination is considered reachable.
 if (nextHop) {
  if (dear->neighbours[nextHop].valid) {
   dear->numIndirectTransmissions++;
   DearSetTxPower(node, dear->defaultPower);   
  } else {
   dear->numDirectTransmissions++;
   DearSetTxPower(node, dear->neighbours[node->nodeId].power);
  }
  
  // Allocate the next hop information header if needed.
  if (nextHopInfoPtr == NULL) {
   MESSAGE_AddInfo(node, msg, sizeof(nextHop), INFO_TYPE_DearNextHop);
   nextHopInfoPtr = (NodeAddress *)MESSAGE_ReturnInfo(msg, INFO_TYPE_DearNextHop);
   assert(nextHopInfoPtr);
  }
  
  // Write the next hop, and route the packet.
  *nextHopInfoPtr = nextHop;
  *packetWasRouted = TRUE;  
  NetworkIpSendPacketToMacLayer(node, msg, DEFAULT_INTERFACE, nextHop);
 }
}
Пример #11
0
/*
 * NAME:        ZigbeeAppServer.
 * PURPOSE:     Models the behaviour of ZigbeeAppServer Server on receiving the
 *              message encapsulated in msg.
 * PARAMETERS:  node - pointer to the node which received the message.
 *              msg - message received by the layer
 * RETURN:      none.
 */
void
ZigbeeAppServer(Node* node, Message* msg)
{
    char error[MAX_STRING_LENGTH];
    AppDataZigbeeappServer *serverPtr;

    switch (msg->eventType)
    {
        case MSG_APP_FromTransport:
        {
            UdpToAppRecv* info = NULL;
            ZigbeeAppData data;
            ERROR_Assert(sizeof(data) <= ZIGBEEAPP_HEADER_SIZE,
                         "ZigbeeAppData size cant be greater than"
                         " ZIGBEEAPP_HEADER_SIZE");

            info = (UdpToAppRecv *) MESSAGE_ReturnInfo(msg);
            memcpy(&data, MESSAGE_ReturnPacket(msg), sizeof(data));

            // trace recd pkt
            ActionData acnData;
            acnData.actionType = RECV;
            acnData.actionComment = NO_COMMENT;
            TRACE_PrintTrace(node,
                             msg,
                             TRACE_APPLICATION_LAYER,
                             PACKET_IN,
                             &acnData);

#ifdef DEBUG
            {
                char clockStr[MAX_STRING_LENGTH];
                char addrStr[MAX_STRING_LENGTH];
                TIME_PrintClockInSecond(data.txTime, clockStr, node);
                IO_ConvertIpAddressToString(&info->sourceAddr, addrStr);

                printf("ZIGBEEAPP Server %ld: packet transmitted at %sS\n",
                       node->nodeId, clockStr);
                TIME_PrintClockInSecond(node->getNodeTime(), clockStr, node);
                printf("    received at %sS\n", clockStr);
                printf("    client is %s\n", addrStr);
                printf("    connection Id is %d\n", data.sourcePort);
                printf("    seqNo is %d\n", data.seqNo);
            }
#endif /* DEBUG */

            serverPtr = ZigbeeAppServerGetServer(node,
                                                 info->sourceAddr,
                                                 data.sourcePort);

            // New connection, so create new ZIGBEEAPP server to handle client.
            if (serverPtr == NULL)
            {
                serverPtr = ZigbeeAppServerNewServer(node,
                                                     info->destAddr,
                                                     info->sourceAddr,
                                                     data.sourcePort);

                if (serverPtr == NULL)
                {
                    sprintf(error, "ZIGBEEAPP Server: Node %d unable to "
                            "allocation server\n", node->nodeId);

                    ERROR_ReportError(error);
                }
            }

            if (data.seqNo >= serverPtr->seqNo || data.isMdpEnabled)
            {
                serverPtr->numBytesRecvd += MESSAGE_ReturnPacketSize(msg);
                serverPtr->sessionLastReceived = node->getNodeTime();

                clocktype delay = node->getNodeTime() - data.txTime;

                serverPtr->maxEndToEndDelay = MAX(delay,
                                                  serverPtr->maxEndToEndDelay);
                serverPtr->minEndToEndDelay = MIN(delay,
                                                  serverPtr->minEndToEndDelay);
                serverPtr->totalEndToEndDelay += delay;
                serverPtr->numPktsRecvd++;

                serverPtr->seqNo = data.seqNo + 1;

                // Calculate jitter.
                clocktype transitDelay = node->getNodeTime()- data.txTime;
                clocktype tempJitter = 0;

                // Jitter can only be measured after receiving
                // two packets.

                if (serverPtr->numPktsRecvd > 1)
                {

                    tempJitter = transitDelay -
                            serverPtr->lastTransitDelay;

                if (tempJitter < 0) {
                    tempJitter = -tempJitter;
                }
                if (serverPtr->numPktsRecvd == 2)
                {
                    serverPtr->actJitter = tempJitter;
                }
                else
                {
                    serverPtr->actJitter +=
                        ((tempJitter - serverPtr->actJitter)/16);
                }
                    serverPtr->totalJitter += serverPtr->actJitter;

                }

                serverPtr->lastTransitDelay = transitDelay;
                // serverPtr->lastPacketReceptionTime = node->getNodeTime();

#ifdef DEBUG
                {
                    char clockStr[24];
                    TIME_PrintClockInSecond(
                        serverPtr->totalEndToEndDelay, clockStr);
                    printf("    total end-to-end delay so far is %sS\n",
                           clockStr);
                }
#endif /* DEBUG */

                if (data.type == 'd')
                {
                    // Do nothing
                }
                else if (data.type == 'c')
                {
                    serverPtr->sessionFinish = node->getNodeTime();
                    serverPtr->sessionIsClosed = TRUE;
                }
                else
                {
                    assert(FALSE);
                }
            }
            break;
        }

        default:
        {
            char buf[MAX_STRING_LENGTH];

            TIME_PrintClockInSecond(node->getNodeTime(), buf, node);
            sprintf(error, "ZIGBEEAPP Server: At time %sS, node %d received "
                    "message of unknown type "
                    "%d\n", buf, node->nodeId, msg->eventType);
            ERROR_ReportError(error);
        }
    }

    MESSAGE_Free(node, msg);
}
Пример #12
0
/*
 * NAME:        ZigbeeAppClientInit.
 * PURPOSE:     Initialize a zigbeeAppClient session.
 * PARAMETERS:  node - pointer to the node,
 *              serverAddr - address of the server,
 *              itemsToSend - number of items to send,
 *              itemSize - size of each packet,
 *              interval - interval of packet transmission rate.
 *              startTime - time until the session starts,
 *              endTime - time until the session ends,
 *              tos - the contents for the type of service field.
 * RETURN:      none.
 */
void
ZigbeeAppClientInit(Node* node,
                    Address clientAddr,
                    Address serverAddr,
                    Int32 itemsToSend,
                    Int32 itemSize,
                    clocktype interval,
                    clocktype startTime,
                    clocktype endTime,
                    unsigned tos)
{
    char error[MAX_STRING_LENGTH];
    AppTimer* timer = NULL;
    AppDataZigbeeappClient* clientPtr = NULL;
    Message* timerMsg = NULL;
    Int32 minSize = 0;
    startTime -= getSimStartTime(node);
    endTime -= getSimStartTime(node);

    ERROR_Assert(sizeof(ZigbeeAppData) <= ZIGBEEAPP_HEADER_SIZE,
                 "ZigbeeAppData size cant be greater than ZIGBEEAPP_HEADER_SIZE");
    minSize = ZIGBEEAPP_HEADER_SIZE;

    // Check to make sure the number of zigbeeApp items is a correct value.
    if (itemsToSend < 0)
    {
        sprintf(error, "ZIGBEEAPP Client: Node %d item to sends needs"
            " to be >= 0\n", node->nodeId);

        ERROR_ReportError(error);
    }

    // Make sure that packet is big enough to carry zigbeeApp data information.
    if (itemSize < minSize)
    {
        sprintf(error, "ZIGBEEAPP Client: Node %d item size needs to be >= %d.\n",
                node->nodeId, minSize);
        ERROR_ReportError(error);
    }


    // Make sure that packet is within max limit.
    if (itemSize > APP_MAX_DATA_SIZE)
    {
        sprintf(error, "ZIGBEEAPP Client: Node %d item size needs to be <= %d.\n",
                node->nodeId, APP_MAX_DATA_SIZE);
        ERROR_ReportError(error);
    }

    // Make sure interval is valid.
    if (interval <= 0)
    {
        sprintf(error, "ZIGBEEAPP Client: Node %d interval needs to be > 0.\n",
                node->nodeId);
        ERROR_ReportError(error);
    }

    // Make sure start time is valid. 
    if (startTime < 0)
    {
        sprintf(error, "ZIGBEEAPP Client: Node %d start time needs to be >= 0.\n",
                node->nodeId);
        ERROR_ReportError(error);
    }

    // Check to make sure the end time is a correct value.
    if (!((endTime > startTime) || (endTime == 0)))
    {
        sprintf(error, "ZIGBEEAPP Client: Node %d end time needs to be > "
            "start time or equal to 0.\n", node->nodeId);

        ERROR_ReportError(error);
    }

    // Validate the given tos for this application.
    if (/*tos < 0 || */tos > 255)
    {
        sprintf(error, "ZIGBEEAPP Client: Node %d should have tos value "
            "within the range 0 to 255.\n",
            node->nodeId);
        ERROR_ReportError(error);
    }

    clientPtr = ZigbeeAppClientNewClient(node,
                                         clientAddr,
                                         serverAddr,
                                         itemsToSend,
                                         itemSize,
                                         interval,
                                         startTime,
                                         endTime,
                                         (TosType) tos);

    if (clientPtr == NULL)
    {
        sprintf(error,
                "ZIGBEEAPP Client: Node %d cannot allocate memory for "
                    "new client\n", node->nodeId);

        ERROR_ReportError(error);
    }

    timerMsg = MESSAGE_Alloc(node,
                             APP_LAYER,
                             APP_ZIGBEEAPP_CLIENT,
                             MSG_APP_TimerExpired);

    MESSAGE_InfoAlloc(node, timerMsg, sizeof(AppTimer));

    timer = (AppTimer *)MESSAGE_ReturnInfo(timerMsg);

    timer->sourcePort = clientPtr->sourcePort;
    timer->type = APP_TIMER_SEND_PKT;

#ifdef DEBUG
    {
        char clockStr[MAX_STRING_LENGTH];
        TIME_PrintClockInSecond(startTime, clockStr, node);
        printf("ZIGBEEAPP Client: Node %ld starting client at %sS\n",
               node->nodeId, clockStr);
    }
#endif /* DEBUG */

    MESSAGE_Send(node, timerMsg, startTime);
}
Пример #13
0
/*
 * NAME:        ZigbeeAppClient
 * PURPOSE:     Models the behaviour of zigbeeAppClient Client on receiving the
 *              message encapsulated in msg.
 * PARAMETERS:  node - pointer to the node which received the message.
 *              msg - message received by the layer
 * RETURN:      none.
 */
void
ZigbeeAppClient(Node* node, Message* msg)
{
    char buf[MAX_STRING_LENGTH];
    char error[MAX_STRING_LENGTH];
    AppDataZigbeeappClient* clientPtr;

#ifdef DEBUG
    TIME_PrintClockInSecond(node->getNodeTime(), buf);
    printf("ZIGBEEAPP Client: Node %ld got a message at %sS\n",
           node->nodeId, buf);
#endif /* DEBUG */

    switch (msg->eventType)
    {
        case MSG_APP_TimerExpired:
        {
            AppTimer* timer;

            timer = (AppTimer *) MESSAGE_ReturnInfo(msg);

#ifdef DEBUG
            printf("ZIGBEEAPP Client: Node %ld at %s got timer %d\n",
                   node->nodeId, buf, timer->type);
#endif /* DEBUG */

            clientPtr = ZigbeeAppClientGetClient(node, timer->sourcePort);

            if (clientPtr == NULL)
            {
                sprintf(error, "ZigbeeApp Client: Node %d cannot find zigbeeApp"
                    " client\n", node->nodeId);

                ERROR_ReportError(error);
            }

            switch (timer->type)
            {
                case APP_TIMER_SEND_PKT:
                {
                    ZigbeeAppData data;
                    //char ZigbeeAppData[ZIGBEEAPP_HEADER_SIZE];

                    memset(&data, 0, sizeof(data));

                    ERROR_Assert(sizeof(data) <= ZIGBEEAPP_HEADER_SIZE,
                                 "ZigbeeAppData size cant be greater than"
                                 " ZIGBEEAPP_HEADER_SIZE");

#ifdef DEBUG
                    printf("ZIGBEEAPP Client: Node %u has %u items left to"
                        " send\n", node->nodeId, clientPtr->itemsToSend);
#endif /* DEBUG */

                    if (((clientPtr->itemsToSend > 1)
                        && (node->getNodeTime() + clientPtr->interval
                            < clientPtr->endTime))
                        || ((clientPtr->itemsToSend == 0)
                        && (node->getNodeTime() + clientPtr->interval
                            < clientPtr->endTime))
                        || ((clientPtr->itemsToSend > 1)
                        &&  (clientPtr->endTime == 0))
                        || ((clientPtr->itemsToSend == 0)
                        &&  (clientPtr->endTime == 0)))
                    {
                        data.type = 'd';
                    }
                    else
                    {
                        data.type = 'c';
                        clientPtr->sessionIsClosed = TRUE;
                        clientPtr->sessionFinish = node->getNodeTime();
                    }

                    data.sourcePort = clientPtr->sourcePort;
                    data.txTime = node->getNodeTime();
                    data.seqNo = clientPtr->seqNo++;

#ifdef DEBUG
                    {
                        char clockStr[MAX_STRING_LENGTH];
                        char addrStr[MAX_STRING_LENGTH];

                        TIME_PrintClockInSecond(node->getNodeTime(), clockStr, node);
                        IO_ConvertIpAddressToString(
                            &clientPtr->remoteAddr, addrStr);

                        printf("ZIGBEEAPP Client: node %ld sending data packet"
                               " at time %sS to ZIGBEEAPP server %s\n",
                               node->nodeId, clockStr, addrStr);
                        printf("    size of payload is %d\n",
                               clientPtr->itemSize);
                    }
#endif /* DEBUG */
                    // Note: An overloaded Function
                    //memset(ZigbeeAppData, 0, ZIGBEEAPP_HEADER_SIZE);
                    //memcpy(ZigbeeAppData, (char *) &data, sizeof(data));

                    clocktype zigbeeAppEndTime = 0;
                    if (clientPtr->endTime == 0 && clientPtr->itemsToSend == 0)
                    {
                            // We cant predict the ZIGBEEAPP end time
                            // end time will be simulation time

                            zigbeeAppEndTime = TIME_ReturnMaxSimClock(node);
                    }
                    else if (clientPtr->endTime == 0)
                    {
                        zigbeeAppEndTime = clientPtr->sessionStart
                            + ((clientPtr->itemsToSend 
                                + clientPtr->numPktsSent)
                                    * clientPtr->interval);
                    }
                    else
                    {
                        zigbeeAppEndTime = clientPtr->endTime;
                    }

                    Message *msg = APP_UdpCreateMessage(
                        node,
                        clientPtr->localAddr,
                        (short) clientPtr->sourcePort,
                        clientPtr->remoteAddr,
                        (short) APP_ZIGBEEAPP_SERVER,
                        TRACE_ZIGBEEAPP,
                        clientPtr->tos);

                    APP_AddHeader(
                        node,
                        msg,
                        &data,
                        ZIGBEEAPP_HEADER_SIZE);

                    ZigbeeAppInfo zainfo = ZigbeeAppInfo();
                    zainfo.priority = clientPtr->tos;
                    zainfo.endTime = zigbeeAppEndTime;
                    zainfo.zigbeeAppInterval = clientPtr->interval;
                    zainfo.zigbeeAppPktSize = clientPtr->itemSize;
                    zainfo.srcAddress = 
                        clientPtr->localAddr.interfaceAddr.ipv4;
                    zainfo.srcPort = clientPtr->sourcePort;
                    APP_AddInfo(
                        node,
                        msg,
                        &zainfo,
                        sizeof(ZigbeeAppInfo),
                        INFO_TYPE_ZigbeeApp_Info);

                    int payloadSize = 
                        clientPtr->itemSize - ZIGBEEAPP_HEADER_SIZE;

                    APP_AddVirtualPayload(node, msg, payloadSize);

                    APP_AddInfo(
                        node,
                        msg,
                        &payloadSize,
                        sizeof(int),
                        INFO_TYPE_DataSize);

                    APP_UdpSend(node, msg);

                    clientPtr->numBytesSent += clientPtr->itemSize;
                    clientPtr->numPktsSent++;
                    clientPtr->sessionLastSent = node->getNodeTime();

                    if (clientPtr->itemsToSend > 0)
                    {
                        clientPtr->itemsToSend--;
                    }

                    if (clientPtr->sessionIsClosed == FALSE)
                    {
                        ZigbeeAppClientScheduleNextPkt(node, clientPtr);
                    }

                    break;
                }

                default:
                {
#ifndef EXATA
                    assert(FALSE);
#endif
                }
            }
            break;
        }
        default:
           TIME_PrintClockInSecond(node->getNodeTime(), buf, node);
           sprintf(error, "ZIGBEEAPP Client: at time %sS, node %d "
                   "received message of unknown type"
                   " %d\n", buf, node->nodeId, msg->eventType);
#ifndef EXATA
           ERROR_ReportError(error);
#endif
    }

    MESSAGE_Free(node, msg);
}
Пример #14
0
//-------------------------------------------------------------------------
// FUNCTION     : NdpHandleProtocolEvent(Node* node, Message* msg)
//
// PURPOSE      : Handling NDP timer related events.
//
// PARAMETER    : node - The node that is handling the event.
//                msg - the event that is being handled
//
// ASSUMPTION   : his function will be called from NetworkIpLayer()
//-------------------------------------------------------------------------
void NdpHandleProtocolEvent(Node* node, Message* msg)
{
    NdpData* ndpData = NdpGetNdpData(node);

    if (ndpData == NULL)
    {
        return;
    }

    switch (msg->eventType)
    {
        case NETWORK_NdpPeriodicHelloTimerExpired:
        {
            // Build and send Hello packet
            NdpSendHelloPacket(node, ndpData);

            // Schedule timer for next hello packet.
            NdpScheduleHelloTimer(node, ndpData->ndpPeriodicHelloTimer);
            break;
        }

        case NETWORK_NdpHoldTimerExpired:
        {
            NdpNeighborStruct* existingNeighborInfo =
                NdpSearchDataInNeighborCache(&(ndpData->ndpNeighborTable),
                    (NdpNeighborStruct*) MESSAGE_ReturnInfo(msg));

            if (existingNeighborInfo != NULL)
            {
                clocktype allowedDelay = (ndpData->numHelloLossAllowed
                    + existingNeighborInfo->neighborHelloInterval) * SECOND;

                clocktype currentTime = node->getNodeTime();

                if (currentTime > (existingNeighborInfo->lastHard
                     + allowedDelay))
                {
                    NdpNeighborStruct deletedNeighbor = {0};

                    // Keep a record of the deleated neighbor.
                    memcpy(&deletedNeighbor, existingNeighborInfo,
                        sizeof(NdpNeighborStruct));

                    // Neighbors Hold time expired. So delete the neighbor.
                    if (NDP_DEBUG)
                    {
                        char ipAddressStr[MAX_STRING_LENGTH] = {0};
                        IO_ConvertIpAddressToString(
                            existingNeighborInfo->source,
                            ipAddressStr);

                        printf("Neighbor to be deleated is %s\n",
                            ipAddressStr);
                        NdpPrintNeighborTable(node, ndpData);
                    }

                    NdpDeleateDataFromNeighborCache(
                        &(ndpData->ndpNeighborTable),
                        existingNeighborInfo);

                    if (NDP_DEBUG)
                    {
                        printf("Neighbor table after deletion:\n");
                        NdpPrintNeighborTable(node, ndpData);
                    }

                    NdpExecuteCallBackFunctions(
                        node,
                        ndpData,
                        deletedNeighbor.source,
                        deletedNeighbor.subnetMask,
                        deletedNeighbor.lastHard,
                        deletedNeighbor.interfaceIndex,
                        FALSE);
                }
                else
                {
                    // Set HoldTime for the neighbor a new.
                    NdpSetHoldTimerForTheNeighbor(
                        node,
                        ndpData,
                        existingNeighborInfo);
                }
            }
            break;
        }

        case MSG_NETWORK_PrintRoutingTable:
        {
            // This case statement is for debugging purpose only
            if (DEBUG_NDP_TEST_NDP_NEIGHBOR_TABLE)
            {
                NdpPrintNeighborTable(node, ndpData);
            }
            break;
        }

        default:
        {
            // Control of the code must not reach here.
            ERROR_Assert(FALSE, "Unknown event in NDP");
            break;
        }
    } // end switch (msg->eventType)
    MESSAGE_Free(node, msg);
}