ns3におけるドキュメントの極意・いち

【　[ns-3.30の使い方](https://qiita.com/dorapon2000/items/72dcc08eb3c8857f5603) → [1](https://qiita.com/dorapon2000/items/5c0c0a399aeee629be63) → [2](https://qiita.com/dorapon2000/items/4b51c1776f65b3fc7d26) → [3] → [4](https://qiita.com/dorapon2000/items/4b95e5658d537c2b5e72) → [5](https://qiita.com/dorapon2000/items/fe8151f7ee6bcc30c72e) → [6](https://qiita.com/dorapon2000/items/494164b004e2f42a4553) → [7](https://qiita.com/dorapon2000/items/fadabf05a9c947bee87c)　】

ネットワークシミュレータであるns3の説明をいくつかにわけて投稿しています．この投稿は「3. ドキュメントの極意・いち」です．

# 3. ドキュメントの極意・いち

頻繁にバージョンが変わり仕様変更があるns3では，参考にしたい記事のコードが古くてエラーが出る等の問題によく直面します．ns3と付き合うためにはドキュメントを自ら読む力が大切です．この記事では，利用できる公式ドキュメントを列挙し，「[2. ネットワーク構築（前編）](https://qiita.com/dorapon2000/items/4b51c1776f65b3fc7d26)」で生じた疑問を解決する例を示します．

- 公式ドキュメント
- ソースコード
- サンプルコード
- 疑問1. NodeContainerのメソッドは他に何があるか
- 疑問2. どんな属性変数があるか
- 疑問3. シナリオファイルで何をインクルードすればいいのか
- まとめ

## 公式ドキュメント

最新版のドキュメントは[ns3公式ページ](https://www.nsnam.org/)の[[Documentation]](https://www.nsnam.org/documentation/) \> [[Latest Release]](https://www.nsnam.org/documentation/latest/)から見つけられます．現在の最新版はns-3.30です．

<img width="1080" alt="nsnam_documentation_full.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32402/14656111-1872-4a1d-15b8-b9c5d8e3964d.png">



利用できるドキュメントは3つです．

- [Manual](https://www.nsnam.org/docs/release/3.30/manual/html/index.html)
  - ns3のアーキテクチャとns3全体に及ぶ基本概念についての説明
  - 乱数やロギング，シミュレーション時間など
- [Model Library](https://www.nsnam.org/docs/release/3.30/models/html/index.html)
  - ns3が有するモデル（いわばクラス）についての説明
  - CSMAやWiFi，エネルギー，モビリティなど
  - 例：LTEを使いたいときはここの[LTE Module](https://www.nsnam.org/docs/release/3.30/models/html/lte.html)を読むとよい
- [API Documentation](https://www.nsnam.org/docs/release/3.30/doxygen/index.html)
  - ns3が有するC++のクラス・属性変数・トレースソースなどの説明
  - Doxygenによって生成される

ドキュメントを見る際はバージョンの違いに注意してください．グーグルから検索すると開発バージョンのドキュメントが表示されます．

<img width="630" alt="doc_dev_ver.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32402/e4e536a0-4fde-ad7d-4cde-f981ba014069.png">

## ソースコード

ソースコードを見た方がはやいという方は，ns3の開発版のコードが[GitLab](https://gitlab.com/nsnam/ns-3-dev/tree/ns-3.30)と[GitHub](https://github.com/nsnam/ns-3-dev-git)で公開されているので，そちらを見るといいです．タグ経由でバージョンを変更してください．GitHubはGitLabをミラーリングしているだけで，少し更新が遅いようです．実際に，ns-3.30のタグづけがまだされていませんでした（2019/09/20時点）．

GitLab: https://gitlab.com/nsnam/ns-3-dev/tree/ns-3.30

<img width="1440" alt="nsnam_gitlab.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32402/f13fd4fc-b19d-48bd-f3bb-7ce6a3d7512b.png">

GitHub: https://github.com/nsnam/ns-3-dev-git

<img width="1206" alt="nsnam_github.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32402/b83cec04-f77b-63f8-be3d-2b0016acc196.png">

## サンプルコード

チュートリアル用のコードや代表的なシミュレーションのサンプルコードはexamples/の中に，各モジュールのサンプルコードはsrc/[module]/examples/にあります．

## 疑問1. NodeContainerのメソッドは他に何があるか

「[2. ネットワーク構築（前編）](https://qiita.com/dorapon2000/items/4b51c1776f65b3fc7d26)」ではNodeContainerがCreate()以外にもAdd()やGet()というメソッドを持つことを説明しました．オブジェクトの調べ方の例として，NodeContainerの他のメソッドを調べてみます．

[API Documentation](https://www.nsnam.org/docs/release/3.30/doxygen/index.html)のページを開き，右上のSearchからNodeContainerと検索します．

![api_sarch_nodecontainer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32402/397f2268-9d71-a573-fead-40f3763104da.png)

候補が出てくるので，[ns3::NodeContainer](https://www.nsnam.org/docs/release/3.30/doxygen/classns3_1_1_node_container.html)をクリックします．NodeContainerクラスの説明ページが現れます．

![api_nodecontainer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32402/13e4300f-0cb6-cd80-507d-56158323e47d.png)

Public Member Functionsにメソッドの一覧が表示されています．各メソッドをクリックすると詳細を見ることができます．Add()やCreate()もありますね．複数あるのはC++のオーバーロードという仕組みです．

知らないメソッドとして[GetN()](https://www.nsnam.org/docs/release/3.30/doxygen/classns3_1_1_node_container.html#a35aed8b8abb7b7988b086f66d15cdda9)と[Begin()](https://www.nsnam.org/docs/release/3.30/doxygen/classns3_1_1_node_container.html#a2bfe1f50688c96e0888b1907e1e2f324)/[End()](https://www.nsnam.org/docs/release/3.30/doxygen/classns3_1_1_node_container.html#a4904853b5d3e86f622a2ef8b4e959e08)がありますが，どのように使うのでしょうか．GetN()は説明文からおそらくイメージつくでしょう．

```c++
// GetN()の例
NodeContainer nodes;
nodes.Create (2);
uint32_t n = nodes.GetN();
std::cout << "nodes.GetN() = " << n << "\n"; // 2
```

問題はBegin()/End()です．こういうときはこれらが使われているコードを[github](https://github.com/nsnam/ns-3-dev-git)上で検索するのがてっとり早いです．検索窓に「NodeContainer Begin」で検索します．

![github_search_begin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32402/db42f113-f71f-50da-bac4-e741a6f70ef3.png)

![github_searchresult_begin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32402/32ce5e4e-ca47-927e-907b-4eae872f1d76.png)

検索結果の2つ目を見ると，どうやらBegin()とEnd()はfor文でセットで使うようだ，ということがわかりました．これはイテレータというC++の機能の1つです．使用例をあげます．

```c++
// Begin(),End()の例
NodeContainer nodes;
nodes.Create (2);
for (auto i = nodes.Begin(); i != nodes.End(); i++)
{
  // iにはPtr<Node>の中身が入る
  // iに対して何かしらの処理をする
}
```

## 疑問2. どんな属性変数があるか

「[2. ネットワーク構築（前編）](https://qiita.com/dorapon2000/items/4b51c1776f65b3fc7d26)」では，P2Pリンクの速度と遅延を属性変数で変えました．リンク速度はPointToPointNetDeviceの"DataRate"で，遅延はPointToPointChannelの"Delay"です．他にP2Pに関するどんな属性変数があるかを調べてみます．

API documentationで「PointToPointNetDevice」を検索して，[ns3::PointToPointNetDeviceクラス](https://www.nsnam.org/docs/release/3.30/doxygen/classns3_1_1_point_to_point_net_device.html)を開き，[More...](https://www.nsnam.org/docs/release/3.30/doxygen/classns3_1_1_point_to_point_net_device.html#details)をクリックします．検索対象は「PointToPointHelper」でないことに注意してください．PointToPointHelperではPointToPointNetDeviceの属性変数を設定していたにすぎません．

![api_attribute.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32402/59e3cb2c-5be0-6e0f-394c-7eeb16b7a6ac.png)

Attributesに設定できる属性変数が列挙されています．DataRateもありますね．他にも，MTUやMACアドレスを属性変数で変更できます．余力があれば[PointToPointChannel](https://www.nsnam.org/docs/release/3.30/doxygen/classns3_1_1_point_to_point_channel.html)の属性変数も検索してみてください．

さて，検索すべきクラスがわからない時や，こんな属性変数があれば使いたい，というときはどうすればいいでしょうか．API documentationには[全ての属性変数を列挙したページ](https://www.nsnam.org/docs/release/3.30/doxygen/_attribute_list.html)があります．

![api_allatributes.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32402/15a8aa7f-91fd-e779-921b-0f1543a148e2.png)

ここからブラウザの検索機能を使って探してみてください．同じ名前の属性変数が別々のクラスで存在することがあるので，その場合はモジュールのドキュメントを読む必要があるかもしれません．



## 疑問3. シナリオファイルで何をインクルードすればいいのか

説明するよりもまず例お見せします．[first.cc](https://gitlab.com/nsnam/ns-3-dev/blob/ns-3.30/examples/tutorial/first.cc)を開いてください．first.ccを上から眺めて，ns3独自の関数名やオブジェクトがあるたびにそれらをAPI documentationで検索してきます．

<img width="949" alt="first_include2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32402/8293ba74-959c-d1db-fb41-f81c6f234d5a.png">

NS_LOG_COMPONENT_DEFINE()を検索するとns3のマクロのようで，log.hに定義があるとわかります．CommandLineを検索するとcommand-line.hをインクルードしろとあります．同様に残りの部分についても検索していき，それらすべてをヘッダファイルとして#includeします．ただし，"ns3/"とつけてください．

```c++
// core module
#include "ns3/simulator.h"
#include "ns3/command-line.h"
#include "ns3/nstime.h"
#include "ns3/uinteger.h"
#include "ns3/string.h"
#include "ns3/log.h"

// network module
#include "ns3/node-container.h"
#include "ns3/net-device-container.h"

// point-to-point module
#include "ns3/point-to-point-helper.h"

// internet module
#include "ns3/internet-stack-helper.h"
#include "ns3/ipv4-address-helper.h"
#include "ns3/ipv4-interface-container.h"

// applications module
#include "ns3/udp-echo-helper.h"
#include "ns3/application-container.h"


```

このようにしてインクルードファイルを列挙していきます．

```c++:first.cc
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
```

さて，これらはfirst.ccで実際に#includeしているファイルとは異なります．しかし両方を見比べるとあることに気づきます．モジュール名に"-module.h"として#includeするとモジュールに含まれる全てのヘッダファイルをインクルードするのです．例えば，"core-module.h"を#includeすると，coreモジュールに含まれる全てのヘッダファイルがインクルードされます．実際にcore-module.hというファイルがあるわけではありません．使用しないヘッダファイルまでインクルードするためビルド時間が長くなりますが，より簡潔に記述できます．好みで使い分けてください．

そのヘッダファイルがどのモジュールに含まれるかは，ヘッダファイルのパスからわかります．

<img width="663" alt="github_find_sarch_log.h.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32402/32310ffe-8f7d-366d-71a5-aa46b36ebe2f.png">

## まとめ

ドキュメントを読めるようになれば，ns3のバージョンアップにも自身で対応できるようになります．

次の記事では[ネットワーク構築（後編）](https://qiita.com/dorapon2000/items/4b95e5658d537c2b5e72)ということで，WifiとEthernetを混ぜたトポロジーを作成する例を示します．