PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/nw-mme-emu/NwMmeMain.c

https://github.com/drb999/nwEPC---EPC-SAE-Gateway
C | 435 lines | 274 code | 78 blank | 83 comment | 75 complexity | c32bc07cb7ee2dc833fd64c20fbff178 MD5 | raw file
  1. /*----------------------------------------------------------------------------*
  2. * *
  3. * n w - m m e *
  4. * L T E / S A E M O B I L I T Y M A N A G E M E N T E N T I T Y *
  5. * *
  6. * *
  7. * Copyright (c) 2010-2011 Amit Chawre *
  8. * All rights reserved. *
  9. * *
  10. * Redistribution and use in source and binary forms, with or without *
  11. * modification, are permitted provided that the following conditions *
  12. * are met: *
  13. * *
  14. * 1. Redistributions of source code must retain the above copyright *
  15. * notice, this list of conditions and the following disclaimer. *
  16. * 2. Redistributions in binary form must reproduce the above copyright *
  17. * notice, this list of conditions and the following disclaimer in the *
  18. * documentation and/or other materials provided with the distribution. *
  19. * 3. The name of the author may not be used to endorse or promote products *
  20. * derived from this software without specific prior written permission. *
  21. * *
  22. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR *
  23. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES *
  24. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. *
  25. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, *
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT *
  27. * NOT LIMITED TO, PROCUREMENT OF SUmmeTITUTE GOODS OR SERVICES; LOSS OF USE, *
  28. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY *
  29. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
  30. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF *
  31. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
  32. *----------------------------------------------------------------------------*/
  33. /**
  34. * @file NwMmeMain.c
  35. * @brief This main file demostrates usage of nw-gtpv2c library for a LTE/SAE MME.
  36. */
  37. #include <stdio.h>
  38. #include <string.h>
  39. #include <assert.h>
  40. #include <event.h>
  41. #include <sys/socket.h>
  42. #include <arpa/inet.h>
  43. #include <stdio.h>
  44. #include <unistd.h>
  45. #include <errno.h>
  46. #include <fcntl.h>
  47. #include "NwLog.h"
  48. #include "NwUtils.h"
  49. #include "NwMmeLog.h"
  50. #include "NwLogMgr.h"
  51. #include "NwTmrMgr.h"
  52. #include "NwGtpv2c.h"
  53. #include "NwMmeUe.h"
  54. #include "NwMmeUlp.h"
  55. #include "NwMmeDpe.h"
  56. #include "NwUdp.h"
  57. /*---------------------------------------------------------------------------
  58. * M M E C L A S S
  59. *--------------------------------------------------------------------------*/
  60. typedef struct
  61. {
  62. NwU32T mmeIpAddr;
  63. NwU32T sgwIpAddr;
  64. NwU32T pgwIpAddr;
  65. NwU32T numOfUe;
  66. NwU32T rps;
  67. NwU32T sessionTimeout;
  68. NwUdpT udp;
  69. NwMmeUlpT ulp;
  70. NwGtpv2cStackHandleT hGtpcStack;
  71. struct {
  72. NwMmeDpeT *pDpe; /*< Data Plane Entity */
  73. NwU32T gtpuIpv4Addr;
  74. NwU8T tunNwIfName[128];
  75. } dataPlane;
  76. } NwMmeT;
  77. /*---------------------------------------------------------------------------
  78. * T M R M G R E N T I T Y C A L L B A C K
  79. *--------------------------------------------------------------------------*/
  80. static void NW_TMR_CALLBACK(nwMmeHandleGtpcv2StackTimerTimeout)
  81. {
  82. NwRcT rc;
  83. /*
  84. * Send Timeout Request to GTPv2c Stack Instance
  85. */
  86. rc = nwGtpv2cProcessTimeout(arg);
  87. NW_ASSERT( NW_OK == rc );
  88. return;
  89. }
  90. NwRcT nwGtpv2TimerStartIndication( NwGtpv2cTimerMgrHandleT tmrMgrHandle,
  91. NwU32T timeoutSec,
  92. NwU32T timeoutUsec,
  93. NwU32T tmrType,
  94. void* timeoutArg,
  95. NwGtpv2cTimerHandleT* phTmr)
  96. {
  97. return nwTmrMgrStartTimer(tmrMgrHandle, timeoutSec, timeoutUsec, tmrType, nwMmeHandleGtpcv2StackTimerTimeout, timeoutArg, (NwTimerHandleT*)phTmr);
  98. }
  99. NwRcT nwGtpv2TimerStopIndication( NwGtpv2cTimerMgrHandleT tmrMgrHandle,
  100. NwGtpv2cTimerHandleT hTmr)
  101. {
  102. return nwTmrMgrStopTimer(tmrMgrHandle, (NwTimerHandleT)hTmr);
  103. }
  104. /*---------------------------------------------------------------------------
  105. * L O G M G R E N T I T Y C A L L B A C K
  106. *--------------------------------------------------------------------------*/
  107. static
  108. NwRcT nwLog (NwGtpv2cLogMgrHandleT hlogMgr,
  109. NwU32T logLevel,
  110. NwCharT* file,
  111. NwU32T line,
  112. NwCharT* logStr)
  113. {
  114. NwLogMgrT* thiz = (NwLogMgrT*) hlogMgr;
  115. if(thiz->logLevel >= logLevel)
  116. {
  117. nwLogMgrLog(&_gLogMgr, "NWGTPCv2 ", logLevel, file, line, logStr);
  118. }
  119. return NW_OK;
  120. }
  121. NwRcT
  122. nwMmeCmdLineHelp()
  123. {
  124. printf("\nSupported command line arguments are:\n");
  125. printf("\n+---------------------------+---------------+---------------------------------------+");
  126. printf("\n| ARGUMENT | PRESENCE | DESCRIPTION |");
  127. printf("\n+---------------------------+---------------+---------------------------------------+");
  128. printf("\n| --mme-ip | -mi | MANDATORY | IP address for the MME control plane. |");
  129. printf("\n| --sgw-ip | -si | MANDATORY | IP address of the target SGW. |");
  130. printf("\n| --pgw-ip | -pi | MANDATORY | IP address of the target PGW. |");
  131. printf("\n| --gtpu-ip | -gi | MANDATORY | IP address for the MME user plane. |");
  132. printf("\n| --num-of-ue | -nu | OPTIONAL | Number of UEs to simulate. |");
  133. printf("\n| --session-timeout | -st | OPTIONAL | UE session timeout in seconds. |");
  134. printf("\n| --reg-per-sec| -rps | OPTIONAL | Session registrations per second. |");
  135. printf("\n| --tun-if | -si | OPTIONAL | Network interface name for tunnel-if. |");
  136. printf("\n+---------------------------+---------------+---------------------------------------+");
  137. printf("\n\nExample Usage: \n$ nwLteMmeEmu --mme-ip 10.0.0.1 --sgw-ip 10.0.0.2 --pgw-ip 10.0.0.3 --gtpu-ip 10.0.0.1 --tun-if eth1 -nu 50000 -st 120 -rps 100\n");
  138. printf("\n");
  139. exit(0);
  140. }
  141. NwRcT
  142. nwMmeParseCmdLineOpts(NwMmeT* thiz, int argc, char* argv[])
  143. {
  144. NwRcT rc = NW_OK;
  145. int i = 0;
  146. /* Set default values */
  147. thiz->rps = 0xffffffff;
  148. thiz->numOfUe = 1;
  149. thiz->mmeIpAddr = 0;
  150. thiz->sgwIpAddr = 0;
  151. thiz->pgwIpAddr = 0;
  152. thiz->sessionTimeout = 0;
  153. strcpy((char*)thiz->dataPlane.tunNwIfName, "");
  154. i++;
  155. while( i < argc )
  156. {
  157. NW_MME_LOG(NW_LOG_LEVEL_DEBG, "Processing cmdline arg %s", argv[i]);
  158. if((strcmp("--sgw-ip", argv[i]) == 0)
  159. || (strcmp(argv[i], "-si") == 0))
  160. {
  161. i++;
  162. if(i >= argc)
  163. return NW_FAILURE;
  164. NW_MME_LOG(NW_LOG_LEVEL_DEBG, "sgw ip %s", argv[i]);
  165. thiz->sgwIpAddr = inet_addr(argv[i]);
  166. }
  167. else if((strcmp("--pgw-ip", argv[i]) == 0)
  168. || (strcmp(argv[i], "-pi") == 0))
  169. {
  170. i++;
  171. if(i >= argc)
  172. return NW_FAILURE;
  173. NW_MME_LOG(NW_LOG_LEVEL_DEBG, "pgw ip %s", argv[i]);
  174. thiz->pgwIpAddr = inet_addr(argv[i]);
  175. }
  176. else if((strcmp("--mme-ip", argv[i]) == 0)
  177. || (strcmp(argv[i], "-mi") == 0))
  178. {
  179. i++;
  180. if(i >= argc)
  181. return NW_FAILURE;
  182. NW_MME_LOG(NW_LOG_LEVEL_DEBG, "mme ip %s", argv[i]);
  183. thiz->mmeIpAddr = inet_addr(argv[i]);
  184. }
  185. else if((strcmp("--gtpu-ip", argv[i]) == 0)
  186. || (strcmp(argv[i], "-gi") == 0))
  187. {
  188. i++;
  189. if(i >= argc)
  190. return NW_FAILURE;
  191. NW_MME_LOG(NW_LOG_LEVEL_DEBG, "User Plane IP address %s", argv[i]);
  192. thiz->dataPlane.gtpuIpv4Addr = ntohl(inet_addr(argv[i]));
  193. }
  194. else if((strcmp("--tun-if", argv[i]) == 0)
  195. || (strcmp(argv[i], "-si") == 0))
  196. {
  197. i++;
  198. if(i >= argc)
  199. return NW_FAILURE;
  200. NW_MME_LOG(NW_LOG_LEVEL_DEBG, "TUN network inteface name %s", argv[i]);
  201. strcpy((char*)thiz->dataPlane.tunNwIfName, (argv[i]));
  202. }
  203. else if((strcmp("--session-timeout", argv[i]) == 0)
  204. || (strcmp(argv[i], "-st") == 0))
  205. {
  206. i++;
  207. if(i >= argc)
  208. return NW_FAILURE;
  209. NW_MME_LOG(NW_LOG_LEVEL_DEBG, "UE Session timeout %s", argv[i]);
  210. thiz->sessionTimeout = atoi(argv[i]);
  211. }
  212. else if((strcmp("--num-of-ue", argv[i]) == 0)
  213. || (strcmp(argv[i], "-nu") == 0))
  214. {
  215. i++;
  216. if(i >= argc)
  217. return NW_FAILURE;
  218. NW_MME_LOG(NW_LOG_LEVEL_DEBG, "number of UE %s", argv[i]);
  219. thiz->numOfUe = atoi(argv[i]);
  220. }
  221. else if((strcmp("--reg-per-sec", argv[i]) == 0)
  222. || (strcmp(argv[i], "-rps") == 0))
  223. {
  224. i++;
  225. if(i >= argc)
  226. return NW_FAILURE;
  227. NW_MME_LOG(NW_LOG_LEVEL_DEBG, "Registration per second %s", argv[i]);
  228. thiz->rps = atoi(argv[i]);
  229. }
  230. else if((strcmp("--help", argv[i]) == 0)
  231. || (strcmp(argv[i], "-h") == 0))
  232. {
  233. nwMmeCmdLineHelp();
  234. }
  235. else
  236. {
  237. rc = NW_FAILURE;
  238. }
  239. i++;
  240. }
  241. if(thiz->mmeIpAddr && thiz->sgwIpAddr && thiz->pgwIpAddr)
  242. {
  243. return rc;
  244. }
  245. else
  246. {
  247. return NW_FAILURE;
  248. }
  249. }
  250. /*---------------------------------------------------------------------------
  251. * T H E M A I N F U N C T I O N
  252. *--------------------------------------------------------------------------*/
  253. int main(int argc, char* argv[])
  254. {
  255. NwRcT rc;
  256. NwMmeT mme;
  257. NwGtpv2cUlpEntityT ulp;
  258. NwGtpv2cUdpEntityT udp;
  259. NwGtpv2cTimerMgrEntityT tmrMgr;
  260. NwGtpv2cLogMgrEntityT logMgr;
  261. /*---------------------------------------------------------------------------
  262. * Initialize LogMgr
  263. *--------------------------------------------------------------------------*/
  264. rc = nwLogMgrInit(nwLogMgrGetInstance(), (NwU8T*)"NW-MME", getpid());
  265. NW_ASSERT(NW_OK == rc);
  266. /*---------------------------------------------------------------------------
  267. * Parse Commandline Arguments
  268. *--------------------------------------------------------------------------*/
  269. rc = nwMmeParseCmdLineOpts(&mme, argc, argv);
  270. if(rc != NW_OK)
  271. {
  272. printf("Usage error. Please refer help.\n");
  273. printf("Example usage: %s --sgw-ip <a.b.c.d> --mme-ip <x.y.z.a> --pgw-ip <e.f.g.h> --num-of-ue 10\n", argv[0]);
  274. exit(0);
  275. }
  276. /*---------------------------------------------------------------------------
  277. * Initialize event library
  278. *--------------------------------------------------------------------------*/
  279. NW_EVT_INIT();
  280. /*---------------------------------------------------------------------------
  281. * Create Data Plane instance.
  282. *--------------------------------------------------------------------------*/
  283. mme.dataPlane.pDpe = nwMmeDpeInitialize();
  284. if(mme.dataPlane.gtpuIpv4Addr)
  285. {
  286. rc = nwMmeDpeCreateGtpuService(mme.dataPlane.pDpe, mme.dataPlane.gtpuIpv4Addr);
  287. }
  288. if(strlen(mme.dataPlane.tunNwIfName) !=0)
  289. {
  290. rc = nwMmeDpeCreateIpv4Service(mme.dataPlane.pDpe, mme.dataPlane.tunNwIfName);
  291. }
  292. /*---------------------------------------------------------------------------
  293. * Initialize GTPv2c Stack Instance
  294. *--------------------------------------------------------------------------*/
  295. rc = nwGtpv2cInitialize(&mme.hGtpcStack);
  296. if(rc != NW_OK)
  297. {
  298. NW_MME_LOG(NW_LOG_LEVEL_ERRO, "Failed to create GTPv2c stack instance. Error '%u' occured", rc);
  299. exit(1);
  300. }
  301. NW_MME_LOG(NW_LOG_LEVEL_INFO, "GTP-Cv2 Stack Handle '%X' Creation Successful!", mme.hGtpcStack);
  302. /* Set up Log Entity */
  303. logMgr.logMgrHandle = (NwGtpv2cLogMgrHandleT) nwLogMgrGetInstance();
  304. logMgr.logReqCallback = nwLog;
  305. rc = nwGtpv2cSetLogMgrEntity(mme.hGtpcStack, &logMgr);
  306. NW_ASSERT( NW_OK == rc );
  307. rc = nwGtpv2cSetLogLevel(mme.hGtpcStack, nwLogMgrGetLogLevel(nwLogMgrGetInstance()));
  308. NW_ASSERT( NW_OK == rc );
  309. /* Set up Timer Entity */
  310. tmrMgr.tmrMgrHandle = 0;
  311. tmrMgr.tmrStartCallback= nwGtpv2TimerStartIndication;
  312. tmrMgr.tmrStopCallback = nwGtpv2TimerStopIndication;
  313. rc = nwGtpv2cSetTimerMgrEntity(mme.hGtpcStack, &tmrMgr);
  314. NW_ASSERT( NW_OK == rc );
  315. /* Initialize and Set up Ulp Entity */
  316. rc = nwMmeUlpInit(&mme.ulp, mme.numOfUe, mme.sessionTimeout, mme.mmeIpAddr, mme.sgwIpAddr, mme.pgwIpAddr, mme.rps, mme.dataPlane.pDpe, mme.hGtpcStack);
  317. NW_ASSERT( NW_OK == rc );
  318. ulp.hUlp = (NwGtpv2cUlpHandleT) &mme.ulp;
  319. ulp.ulpReqCallback = nwMmeUlpStackReqCallback;
  320. rc = nwGtpv2cSetUlpEntity(mme.hGtpcStack, &ulp);
  321. NW_ASSERT( NW_OK == rc );
  322. /* Initialize and Set up Udp Entity */
  323. rc = nwUdpInit(&mme.udp, mme.mmeIpAddr, mme.hGtpcStack);
  324. NW_ASSERT( NW_OK == rc );
  325. udp.hUdp = (NwGtpv2cUdpHandleT)&mme.udp;
  326. udp.udpDataReqCallback = nwUdpDataReq;
  327. rc = nwGtpv2cSetUdpEntity(mme.hGtpcStack, &udp);
  328. NW_ASSERT( NW_OK == rc );
  329. /*---------------------------------------------------------------------------
  330. * Start Network Entry Procedure from ULP
  331. *--------------------------------------------------------------------------*/
  332. rc = nwMmeUlpStartNetworkEntry(&mme.ulp);
  333. NW_ASSERT( NW_OK == rc );
  334. /*---------------------------------------------------------------------------
  335. * Event Loop
  336. *--------------------------------------------------------------------------*/
  337. NW_EVT_LOOP();
  338. NW_MME_LOG(NW_LOG_LEVEL_ERRO, "Exit from eventloop, no events to process!");
  339. /*---------------------------------------------------------------------------
  340. * Destroy ULP instance
  341. *--------------------------------------------------------------------------*/
  342. rc = nwMmeUlpDestroy(&mme.ulp);
  343. NW_ASSERT( NW_OK == rc );
  344. /*---------------------------------------------------------------------------
  345. * Destroy GTPv2c Stack Instance
  346. *--------------------------------------------------------------------------*/
  347. rc = nwGtpv2cFinalize(mme.hGtpcStack);
  348. if(rc != NW_OK)
  349. {
  350. NW_MME_LOG(NW_LOG_LEVEL_ERRO, "Failed to finalize GTPv2c stack instance. Error '%u' occured", rc);
  351. }
  352. else
  353. {
  354. NW_MME_LOG(NW_LOG_LEVEL_INFO, "GTP-Cv2 Stack Handle '%x' Finalize Successful!", mme.hGtpcStack);
  355. }
  356. return rc;
  357. }