evpLocal.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. #include "evpLocal.h"
  2. server_info g_server; /* server information */
  3. word g_sequence = 0;
  4. int g_sockId = -1; /* server socket connect id */
  5. char g_serverConn = D_SERVER_DISCONNECT; /* server connect flag */
  6. char g_serverLogin= D_SERVER_DISCONNECT; /* server connect flag */
  7. int g_termApp = D_TERMAPP_NO; /* app terminate flag */
  8. struct tm g_tmTod; /* system time variable */
  9. char g_serviceId[EVPS_SERVICE_ID_SIZE+1];
  10. /*
  11. ***************************************************************************************************
  12. * global variables
  13. ***************************************************************************************************/
  14. char* BuildTime = __DATE__ " " __TIME__;
  15. char* AppName = "evpLocal";
  16. int _LogWrite(const char *fmt, ...)
  17. {
  18. va_list args;
  19. va_start(args, fmt);
  20. vfprintf(stderr, fmt, args);
  21. va_end(args);
  22. return 1;
  23. }
  24. int _read_config_file()
  25. {
  26. char *pServerIp = "10.4.4.51";
  27. //char *pServerIp = "192.168.20.91";
  28. memset((char*)&g_server, 0x00, sizeof(g_server));
  29. memcpy(g_server.ipaddr, pServerIp, strlen(pServerIp));
  30. g_server.port = 7800;
  31. _LogWrite("EVPS SERVER: %s::%d\n", g_server.ipaddr, g_server.port);
  32. return 0;
  33. }
  34. void _getNetTime(struct tm *localTod)
  35. {
  36. time_t localTime;
  37. localTime = time(NULL);
  38. localtime_r(&localTime, localTod);
  39. }
  40. void _cliEpipe(int sig)
  41. {
  42. _LogWrite("[ERROR] SIGPIPE.........\n");
  43. signal(SIGPIPE, _cliEpipe);
  44. }
  45. void _cliBreak(int sig)
  46. {
  47. _LogWrite("[ERROR] SIGUSR1.........\n");
  48. g_termApp = D_TERMAPP_YES;
  49. }
  50. void _cliNetDisconnected(void)
  51. {
  52. if (g_sockId > 0)
  53. {
  54. close(g_sockId);
  55. g_sockId = -1;
  56. }
  57. g_serverConn = D_SERVER_DISCONNECT;
  58. }
  59. int _cliInit(void)
  60. {
  61. char opt;
  62. struct sockaddr_in client;
  63. if (g_serverConn == D_SERVER_CONNECT)
  64. {
  65. return g_serverConn;
  66. }
  67. if ((g_sockId = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  68. {
  69. g_serverConn = D_SERVER_DISCONNECT;
  70. return g_serverConn;
  71. }
  72. memset((char *) &client, 0x00, sizeof(client));
  73. client.sin_family = AF_INET;
  74. client.sin_addr.s_addr = inet_addr(g_server.ipaddr);
  75. client.sin_port = htons(g_server.port);
  76. opt = 1;
  77. setsockopt(g_sockId, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(int));
  78. setsockopt(g_sockId, SOL_SOCKET, SO_KEEPALIVE, (char*)&opt, sizeof(int));
  79. if (connect(g_sockId, (struct sockaddr *)&client, sizeof(struct sockaddr_in)) < 0)
  80. {
  81. _LogWrite("NetWork Connected..Error...\n");
  82. _cliNetDisconnected();
  83. return g_serverConn;
  84. }
  85. g_serverConn = D_SERVER_CONNECT;
  86. g_serverLogin = D_SERVER_DISCONNECT;
  87. _LogWrite("NetWork Connected...\n");
  88. return g_serverConn;
  89. }
  90. void dumpData(char *AData, int ALen)
  91. {
  92. int ii, jj, pos;
  93. fprintf(stderr, "\nDATA DUMP***************\n");
  94. for(ii = 0; ii < ALen; ii += 16) {
  95. for(jj = 0; jj < 16; ++jj) {
  96. pos = ii + jj;
  97. if (pos >= ALen) {
  98. break;
  99. }
  100. fprintf(stderr, "%02X ", (byte)(AData[pos] & 0xFF));
  101. }
  102. fprintf(stderr, "\n");
  103. }
  104. fprintf(stderr, "\n\n");
  105. }
  106. int _cliSend(char* AData, int APktSize)
  107. {
  108. int writeCount;
  109. dumpData(AData, APktSize);
  110. if ((writeCount = send(g_sockId, AData, APktSize, 0)) <= 0)
  111. {
  112. fprintf(stderr, "DATA Send Failed!!!\n");
  113. _cliNetDisconnected();
  114. return -1;
  115. }
  116. fprintf(stderr, "DATA Send %d Bytes, RC(%d)!!!\n", APktSize, writeCount);
  117. usleep(10000);
  118. return 0;
  119. }
  120. void makeHead(pkt_headp pHead, byte opCode, word sequence, word current, word total, word length)
  121. {
  122. _getNetTime(&g_tmTod);
  123. memset(pHead, 0x00, sizeof(pkt_head));
  124. pHead->stx1 = EVPS_STX1;
  125. pHead->stx2 = EVPS_STX2;
  126. pHead->opCode = opCode;
  127. SETWORD(pHead->sequence, sequence);
  128. SETWORD(pHead->current, current);
  129. SETWORD(pHead->total, total);
  130. SETWORD(pHead->year, g_tmTod.tm_year+1900);
  131. pHead->month = g_tmTod.tm_mon+1;
  132. pHead->day = g_tmTod.tm_mday;
  133. pHead->hour = g_tmTod.tm_hour;
  134. pHead->min = g_tmTod.tm_min;
  135. pHead->sec = g_tmTod.tm_sec;
  136. memcpy(pHead->serviceId, g_serviceId, EVPS_SERVICE_ID_SIZE);
  137. SETWORD(pHead->dataLength, length);
  138. //fprintf(stderr, "***** HEAD: %02X, SEQ: %d, CUR: %d, TOT: %d, LENGTH: %d, SERIVCE ID: %s\n", opCode, sequence, current, total, length, g_serviceId);
  139. }
  140. void sendEvpsData(byte opCode, char *pData, int length)
  141. {
  142. evps_pkt pkt;
  143. int sequence = g_sequence++;
  144. int ii, idx, current, total, dataSize;
  145. current = 1;
  146. total = (length / MAX_DATA_SIZE) + 1;
  147. if (0 == (length % MAX_DATA_SIZE)) {
  148. total--;
  149. }
  150. for (ii = 0; ii < total; ii++) {
  151. dataSize = MAX_DATA_SIZE;
  152. if ((ii+1) * MAX_DATA_SIZE > length) {
  153. dataSize = length - (MAX_DATA_SIZE * ii);
  154. }
  155. fprintf(stderr, "ServiceId: %s, OpCode: %02X, Sequence: %d, Total: %d, Current: %d, DataLength: %d\n", g_serviceId, opCode, sequence, total, current, dataSize);
  156. makeHead(&pkt.head, opCode, sequence, current++, total, dataSize);
  157. idx = ii*MAX_DATA_SIZE;
  158. memcpy(&pkt.data[0], &pData[idx], dataSize);
  159. _cliSend((char*)&pkt, sizeof(pkt_head) + dataSize);
  160. }
  161. }
  162. void makeServiceId() {
  163. _getNetTime(&g_tmTod);
  164. memset(g_serviceId, 0x00, sizeof(g_serviceId));
  165. sprintf(g_serviceId, "184%04d%02d%02d%02d%02d%02d01", g_tmTod.tm_year+1900, g_tmTod.tm_mon+1, g_tmTod.tm_mday, g_tmTod.tm_hour, g_tmTod.tm_min, g_tmTod.tm_sec);
  166. }
  167. void sendService()
  168. {
  169. service pkt;
  170. int routeList = 10;
  171. int dataLength;
  172. fprintf(stderr, "1. 긴급차량우선신호 발생에 따른 출발지-목적지 사이의 경로정보\n");
  173. memset((char*)&pkt, 0x00, sizeof(pkt));
  174. dataLength = sizeof(service_veh) + (routeList * sizeof(pos));
  175. makeHead(&pkt.head, EVPS_SERVICE, g_sequence++, 1, 1, dataLength);
  176. strcpy(pkt.veh.evNo, "998나1655"); //차량 번호
  177. pkt.veh.current.lat = htonl( 37.692329 * 1000000); //현재위치LAT, LNG
  178. pkt.veh.current.lng = htonl(126.746276 * 1000000); //현재위치LAT, LNG
  179. strcpy(pkt.veh.serviceName, "인제대학교일산백병원 응급의료센터"); //서비스명
  180. pkt.veh.arrival.lat = htonl( 37.674431 * 1000000); //도착위치LAT, LNG
  181. pkt.veh.arrival.lng = htonl(126.750063 * 1000000); //도착위치LAT, LNG
  182. pkt.veh.vehicleLength = htonl(43); //차량길이(군집차량 길이 포함)
  183. strcpy(pkt.veh.ocrNo, "XZ4137118774"); //재난번호
  184. strcpy(pkt.veh.ocrType, "구급"); //재난종별명
  185. pkt.veh.arrivalTime = htonl(462); //예상도착시각
  186. pkt.veh.distance = htonl(2838); //거리
  187. SETWORD(pkt.veh.routeList, routeList); //경로수
  188. for (int ii = 0; ii < routeList; ii++) {
  189. pkt.route[ii].lat = htonl(( 37.692329+ii) * 1000000);
  190. pkt.route[ii].lng = htonl((126.746276+ii) * 1000000);
  191. }
  192. _cliSend((char*)&pkt, sizeof(pkt.head)+dataLength);
  193. }
  194. void sendNode()
  195. {
  196. service_node pkt;
  197. node_info node;
  198. int idx;
  199. int dataLength;
  200. int nodeList = 2;
  201. int phaseList;
  202. int ii;
  203. int nodeSize;
  204. fprintf(stderr, "2. 경로 내의 교차로/현시구성 정보\n");
  205. memset((char*)&pkt, 0x00, sizeof(pkt));
  206. dataLength = 0;
  207. idx = 0;
  208. SETWORD(pkt.lcList, nodeList);
  209. memset((char*)&node, 0x00, sizeof(node));
  210. phaseList = 5;
  211. nodeSize = (phaseList * sizeof(node_phase)) + 114;
  212. dataLength += nodeSize;
  213. node.intLcNo = htonl(2147483647); //교차로 번호
  214. strcpy(node.intName, "향남힐링스파 사거리"); //교차로명
  215. node.location.lat = htonl( 37.692329 * 1000000); //현재위치LAT, LNG
  216. node.location.lng = htonl(126.746276 * 1000000); //현재위치LAT, LNG
  217. SETWORD(node.phaseList, phaseList); //현시 정보
  218. for (ii = 0; ii < phaseList; ii++) {
  219. node.phase[ii].intRing = (ii % 2) + 1; //링번호, A링(1)/B링(2)
  220. node.phase[ii].intPhaseNo = ii; //현시정보, 1-8
  221. node.phase[ii].intPlanClass = ii; //맵 번호, 맵 번호 (0: 일반제, 1~5: 시차제, 6: 전용맵)
  222. node.phase[ii].intFlowNo = ii+1; //이동류번호, 이동류번호(1-16, 17, 18)
  223. node.phase[ii].intHead.lat = htonl(( 37.692329+ii) * 1000000);
  224. node.phase[ii].intHead.lng = htonl((126.746276+ii) * 1000000);
  225. node.phase[ii].intMiddle.lat = htonl(( 37.692329+ii) * 1000000);
  226. node.phase[ii].intMiddle.lng = htonl((126.746276+ii) * 1000000);
  227. node.phase[ii].intEnd.lat = htonl(( 37.692329+ii) * 1000000);
  228. node.phase[ii].intEnd.lng = htonl((126.746276+ii) * 1000000);
  229. SETWORD(node.phase[ii].intHeadAngle, 90); //시작점각도
  230. SETWORD(node.phase[ii].intEndAngle, 180); //종점각도
  231. }
  232. memcpy(&pkt.data[idx], (char*)&node, nodeSize);
  233. idx += nodeSize;
  234. memset((char*)&node, 0x00, sizeof(node));
  235. phaseList = 3;
  236. nodeSize = (phaseList * sizeof(node_phase)) + 114;
  237. dataLength += nodeSize;
  238. node.intLcNo = htonl(2147483650); //교차로 번호
  239. strcpy(node.intName, "향남힐링스파 AAA"); //교차로명
  240. node.location.lat = htonl( 37.692329 * 1000000); //현재위치LAT, LNG
  241. node.location.lng = htonl(126.746276 * 1000000); //현재위치LAT, LNG
  242. SETWORD(node.phaseList, phaseList); //현시 정보
  243. for (ii = 0; ii < phaseList; ii++) {
  244. node.phase[ii].intRing = (ii % 2) + 1; //링번호, A링(1)/B링(2)
  245. node.phase[ii].intPhaseNo = ii; //현시정보, 1-8
  246. node.phase[ii].intPlanClass = ii; //맵 번호, 맵 번호 (0: 일반제, 1~5: 시차제, 6: 전용맵)
  247. node.phase[ii].intFlowNo = ii+1; //이동류번호, 이동류번호(1-16, 17, 18)
  248. node.phase[ii].intHead.lat = htonl(( 37.692329+ii) * 1000000);
  249. node.phase[ii].intHead.lng = htonl((126.746276+ii) * 1000000);
  250. node.phase[ii].intMiddle.lat = htonl(( 37.692329+ii) * 1000000);
  251. node.phase[ii].intMiddle.lng = htonl((126.746276+ii) * 1000000);
  252. node.phase[ii].intEnd.lat = htonl(( 37.692329+ii) * 1000000);
  253. node.phase[ii].intEnd.lng = htonl((126.746276+ii) * 1000000);
  254. SETWORD(node.phase[ii].intHeadAngle, 90); //시작점각도
  255. SETWORD(node.phase[ii].intEndAngle, 180); //종점각도
  256. }
  257. memcpy(&pkt.data[idx], (char*)&node, nodeSize);
  258. idx += nodeSize;
  259. makeHead(&pkt.head, EVPS_NODE, g_sequence++, 1, 1, dataLength+2);
  260. _cliSend((char*)&pkt, sizeof(pkt.head)+dataLength+2);
  261. }
  262. void sendEvent()
  263. {
  264. service_event pkt;
  265. fprintf(stderr, "3. 긴급차량의 위치와 속도 정보\n");
  266. memset((char*)&pkt, 0x00, sizeof(pkt));
  267. makeHead(&pkt.head, EVPS_EVENT, g_sequence++, 1, 1, sizeof(veh_event));
  268. strcpy(pkt.event.evNo, "998나1655"); //차량 번호
  269. pkt.event.current.lat = htonl( 37.692329 * 1000000); //현재위치LAT, LNG
  270. pkt.event.current.lng = htonl(126.746276 * 1000000); //현재위치LAT, LNG
  271. pkt.event.speed = htonl(22); //차량길이(군집차량 길이 포함)
  272. pkt.event.distance = htonl(333); //잔여 거리
  273. _cliSend((char*)&pkt, sizeof(pkt));
  274. }
  275. void sendSignal()
  276. {
  277. service_signal pkt;
  278. int ii;
  279. int dataLength;
  280. int signalList = 2;
  281. fprintf(stderr, "4. 긴급차량의 위치에서 진행방향의 각 교차로까지의 남은거리 및 현시현황\n");
  282. memset((char*)&pkt, 0x00, sizeof(pkt));
  283. dataLength = signalList * sizeof(signal_info);
  284. for (ii = 0; ii < signalList; ii++) {
  285. pkt.signal[ii].intLcNo = htonl(2147483650+ii); //교차로 번호, 국토부 표준 NODE ID
  286. pkt.signal[ii].remainDist = htonl(111110+ii); //교차로 남은거리
  287. pkt.signal[ii].state = ii % 6; //교차로운영상태, 0: 통신이상, 1: 정상, 2: 점멸, 3: 소등, 4: 수동진행, 5: 현시유지
  288. pkt.signal[ii].plan = ii % 6; //현재 운영중인 맵 번호, 맵 번호(0: 일반제, 1~5: 시차제, 6: 전용맵)
  289. pkt.signal[ii].ARingPhase = (ii % 8) + 1; //A링 현시번호, 현시번호(1-8)
  290. pkt.signal[ii].BRingPhase = (ii % 8) + 1; //B링 현시번호, 현시번호(1-8)
  291. pkt.signal[ii].holdPhase = (ii % 8) + 1; //유지현시번호, 현시번호(1-8)
  292. }
  293. SETWORD(pkt.signalList, signalList);
  294. makeHead(&pkt.head, EVPS_SIGNAL, g_sequence++, 1, 1, dataLength+2);
  295. _cliSend((char*)&pkt, sizeof(pkt.head)+dataLength+2);
  296. }
  297. void sendServiceEnd()
  298. {
  299. service_end pkt;
  300. memset((char*)&pkt, 0x00, sizeof(pkt));
  301. fprintf(stderr, "5. 긴급차량 서비스 종료\n");
  302. makeHead(&pkt.head, EVPS_SERVICE_END, g_sequence++, 1, 1, 4);
  303. pkt.reason = htonl(2);
  304. _cliSend((char*)&pkt, sizeof(pkt));
  305. }
  306. int getSendOption() {
  307. int opt;
  308. fprintf(stderr, "****** Input Test Data Send Options\n");
  309. fprintf(stderr, " 1. 긴급차량우선신호 발생에 따른 출발지-목적지 사이의 경로정보\n");
  310. fprintf(stderr, " 2. 경로 내의 교차로/현시구성 정보\n");
  311. fprintf(stderr, " 3. 긴급차량의 위치와 속도 정보\n");
  312. fprintf(stderr, " 4. 긴급차량의 위치에서 진행방향의 각 교차로까지의 남은거리 및 현시현황\n");
  313. fprintf(stderr, " 5. 긴급차량 서비스 종료\n");
  314. fprintf(stderr, " 0. Exit\n");
  315. fprintf(stderr, "Input Option: ");
  316. opt = getchar();
  317. return opt;
  318. }
  319. int main(int AArgc, char* AArgv[])
  320. {
  321. int opt;
  322. fprintf(stderr, "pkt_head: %ld\n", sizeof(pkt_head));
  323. fprintf(stderr, " dword: %ld\n", sizeof(dword));
  324. fprintf(stderr, " time_t: %ld\n", sizeof(time_t));
  325. _getNetTime(&g_tmTod);
  326. #if 1
  327. signal(SIGUSR1, _cliBreak);
  328. signal(SIGPIPE, _cliEpipe);
  329. signal(SIGINT, SIG_IGN);
  330. #endif
  331. _LogWrite("\n");
  332. _LogWrite("\n");
  333. _LogWrite("**********************************************************\n");
  334. _LogWrite(" KoROAD EVPS Local Client Test Program !!!\n");
  335. _LogWrite(" %s \n", BuildTime);
  336. _LogWrite(" %04d/%02d/%02d %02d:%02d:%02d \n", g_tmTod.tm_year+1900, g_tmTod.tm_mon+1, g_tmTod.tm_mday, g_tmTod.tm_hour, g_tmTod.tm_min, g_tmTod.tm_sec);
  337. _LogWrite("**********************************************************\n");
  338. _LogWrite("\n");
  339. /*
  340. * ȯ�漳���� ���� �б�. ./signal.cfg
  341. */
  342. if (_read_config_file() < 0)
  343. {
  344. _LogWrite("[ERROR] config file loading failed...\n");
  345. return 0;
  346. }
  347. if (_cliInit() == D_SERVER_DISCONNECT)
  348. {
  349. _LogWrite("[ERROR] Evps Server Connect failed...\n");
  350. return 0;
  351. }
  352. //opt = getSendOption();
  353. makeServiceId();
  354. while (g_termApp != D_TERMAPP_YES)
  355. {
  356. opt = getSendOption();
  357. _getNetTime(&g_tmTod);
  358. switch(opt) {
  359. case '1': sendService(); break;
  360. case '2': sendNode(); break;
  361. case '3': sendEvent(); break;
  362. case '4': sendSignal(); break;
  363. case '5': sendServiceEnd(); break;
  364. case '0': g_termApp = D_TERMAPP_YES; break;
  365. }
  366. }
  367. _cliNetDisconnected();
  368. }