poc.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. #include "includes.h"
  2. //poc login condition ctl handler start...////////////////////////////////
  3. static T_BOOL loginEnable(void){
  4. static T_BOOL lastLoginStatus=FALSE;
  5. T_BOOL needClose=FALSE;
  6. if(FALSE==talking.remoteEnable){
  7. if(TCP_INIT != talking.tcpLoginStatus) closeTalk();
  8. talking.functionEnable=FALSE;
  9. return FALSE;
  10. }
  11. if(lastLoginStatus != talking.keepLogin){
  12. if(FALSE==talking.keepLogin) needClose=TRUE;
  13. lastLoginStatus=talking.keepLogin;
  14. }
  15. if(TRUE==talking.reLogin) needClose=TRUE;
  16. if(TRUE==needClose) closeTalk();
  17. if(TRUE==talking.reLogin){
  18. talking.reLogin=FALSE;
  19. talking.keepLogin=TRUE;
  20. }
  21. talking.functionEnable=talking.keepLogin;
  22. return talking.keepLogin;
  23. }
  24. static void pocTcpDataHandler(T_UINT8 *msg, T_UINT16 len){
  25. static T_INT32 length=0;
  26. static T_UINT8 pocbuf[GU_NAME_SIZE+50];
  27. T_UINT8 *tempBuf=msg,head, tail;
  28. T_UINT16 tempLen=len;
  29. T_INT8 ret;
  30. #if 1
  31. T_UINT16 i;
  32. for(i=0;i<len;i++){
  33. if(length<sizeof(pocbuf)) pocbuf[length++]=msg[i];
  34. else{
  35. wlog_warn("poc tcp buf over,rst");
  36. length=0;
  37. continue;
  38. }
  39. if(pocbuf[0] != 0x7e){
  40. length=0;
  41. continue;
  42. }
  43. if(length >1 && msg[i]==0x7e){
  44. pocTcpRx(pocbuf,length);
  45. length=0;
  46. }
  47. }
  48. #else
  49. //fill packet
  50. head=tempBuf[0];
  51. tail=tempBuf[tempLen-1];
  52. wlog_info("reclen=%d,head=%02x,tail=%02x",tempLen,head,tail);
  53. if(head==0x7e && tail==0x7e){
  54. //completed packet
  55. if(tempLen > sizeof(pocbuf)) ret=1;//buffer full
  56. else{
  57. length=tempLen;
  58. memcpy(pocbuf, tempBuf, length);
  59. ret=0;//good or full packet
  60. }
  61. }else if(head==0x7e && tail != 0x7e){
  62. //first fench packet
  63. length=tempLen;
  64. if(tempLen > sizeof(pocbuf)) ret=1;//buffer full
  65. else{
  66. length=tempLen;
  67. memcpy(pocbuf, tempBuf, length);
  68. ret=2;//need second packet
  69. }
  70. }else if(head!=0x7e && tail == 0x7e){
  71. //last fench packet
  72. if((tempLen+length) > sizeof(pocbuf)) ret=1;//buffer full
  73. else{
  74. memcpy(pocbuf+length, tempBuf, tempLen);
  75. length += tempLen;
  76. ret=0;//good or full packet
  77. }
  78. }else{
  79. //middle packet or bad packet
  80. if((tempLen+length) > sizeof(pocbuf)) ret=1;//buffer full
  81. else{
  82. if(length==0) ret=4;
  83. else{
  84. memcpy(pocbuf+length, tempBuf, tempLen);
  85. length += tempLen;
  86. ret=3;//middle packet
  87. }
  88. }
  89. }
  90. if(ret ==0){
  91. pocTcpRx(pocbuf,length);
  92. length=0;
  93. }else if(ret == 1){
  94. wlog_warn("buffer full");
  95. length=0;
  96. }else if(ret==4){
  97. wlog_warn("bad packet");
  98. length=0;
  99. }
  100. #endif
  101. }
  102. static void pocBeingClose(void){
  103. T_UINT32 subtime;
  104. T_INT8 info[50];
  105. wlog_warn("pocClose, updateData");
  106. talking.pttReqStatus=FALSE;//连接断掉后,如果当前在请麦
  107. talking.hasVoicePri=FALSE;
  108. pocStopPlayer();
  109. pocStopRecord();
  110. talking.netWork.tcp=0;
  111. if(TCP_ONLINE_IDLE==talking.tcpLoginStatus){
  112. snprintf(info, sizeof(info), "+POC:8200%08x\r\n", get_uid());
  113. msgToOutter(info);
  114. }
  115. talking.tcpLoginStatus=TCP_INIT;
  116. if(talking.loginAckAlready==FALSE)updateLineStatus(LINES_ACCOUNT_ERR, S_CLEAR);
  117. else talking.loginAckAlready=FALSE;
  118. subtime=getSysTick() - talking.conFailType.time;
  119. if(subtime <100){
  120. if(++talking.conFailType.count>=3){
  121. updateLineStatus(LINES_UN_CONNECT_IP, S_SET);
  122. talking.conFailType.count=0;
  123. }
  124. }
  125. else if(subtime > 500){//连接花很长时间才响应失败的连接,IP认为不可连接
  126. updateLineStatus(LINES_UN_CONNECT_IP, S_SET);
  127. }
  128. }
  129. static TUPSEND_DEF tupsendPara;
  130. void pocRecv_cb(void *param){
  131. // T_UINT8 pocTcpBuf[1024];
  132. unsigned char *pdata;
  133. int len_ret;
  134. nwy_osiEvent_t *pEvent = (nwy_osiEvent_t *)param;
  135. TUPSEND_DEF *para=(TUPSEND_DEF *)pEvent->param3;
  136. bool needtoclose=false;
  137. showTupEventInfo("poc",pEvent->id,para,1);
  138. switch(pEvent->id){
  139. case TUP_EVENT_SOCK_LINK_OK:
  140. wlog_info("poc connect server ok:%d",para->fd);
  141. talking.tcpSocket=para->fd;
  142. talking.netWork.tcp=1;
  143. break;
  144. case TUP_EVENT_SOCK_LINK_CLIENT_SHUT:
  145. wlog_warn("poc client close done");
  146. *para->defPara=TUP_STATUS_FALSE;//触发重新连接
  147. needtoclose=true;
  148. break;
  149. case TUP_EVENT_SOCK_LINK_RECV:
  150. pdata=(unsigned char *)pEvent->param1;
  151. len_ret=pEvent->param2;
  152. pocTcpDataHandler(pdata, len_ret);
  153. if(talking.accountError==TRUE){
  154. talking.accountError=FALSE;
  155. wlog_info("poc dly close for account error");
  156. userCloseSocket(&para->fd);//账号信息错误时,服务器会主动关掉终端,这里作了延迟关闭fd)
  157. }
  158. break;
  159. case TUP_EVENT_SOCK_LINK_SERVER_SHUT:
  160. wlog_warn("poc server close done");
  161. *para->defPara=TUP_STATUS_FALSE;//非定向
  162. needtoclose=true;
  163. break;
  164. case TUP_EVENT_SOCK_LINK_ERR:
  165. wlog_error("poc server err,retry");
  166. *para->defPara=TUP_STATUS_FALSE;//连接错误/失败
  167. needtoclose=true;
  168. break;
  169. default: break;
  170. }
  171. if(needtoclose==true){
  172. if(talking.tcpSocket!=0) talking.tcpSocket=0;
  173. pocBeingClose();
  174. }
  175. // LSAPI_OSI_Free(pEvent);
  176. // if(needtoclose==true) threadPostEvent(nwy_get_current_thread(),USER_EVENT_EXIT);
  177. }
  178. PT_THREAD (ptPocLoginConditionTask(pt_timer_t *ptPool, struct pt *pt)){
  179. static pt_timer_t ptTimer;
  180. static T_UINT8 index;
  181. static T_UINT8 printfCnt=0;
  182. static TUP_CONNECT_ENUM tupCStatus=TUP_STATUS_FALSE;
  183. T_UINT8 ret;
  184. PT_BEGIN(pt);
  185. while(1){
  186. if(1==talking.netWork.reg){
  187. //loginEnable();
  188. //if(0){
  189. if(TRUE==loginEnable()){//login is enable , is avaliable to pull tcp up
  190. if(0==talking.netWork.tcp){//tcp is off , need to pull up
  191. ticketDeVote(TICKET_PT_LOGINCON);
  192. #if 0
  193. if(LINES_ACCOUNT_ERR==getLineStatus()){//we meet account err ack, we can slow down the pull interval
  194. if(++talking.netWork.tcpAccountErrReCnt>=5) talking.netWork.tcpAccountErrReCnt=0;
  195. }else talking.netWork.tcpAccountErrReCnt=0;
  196. #else
  197. //只要是新连接,我们都不要那么快
  198. if(++talking.netWork.tcpAccountErrReCnt>=3) talking.netWork.tcpAccountErrReCnt=0;
  199. #endif
  200. if(talking.netWork.tcpAccountErrReCnt==0 && TUP_STATUS_WAIT != tupCStatus){//ready to try to pull up tcp
  201. tupsendPara.defPara=&tupCStatus;
  202. if(TRUE==setDomainForIp(paras.pocServer.addr, &index)){//if set ok , we wait for result
  203. while(1){
  204. ret=getDomainForIp(index, paras.pocServer.ip, sizeof(paras.pocServer.ip));
  205. if(DOMAIN_ERR==ret){
  206. wlog_warn("domain failed");
  207. break;
  208. }else if(DOMAIN_OK==ret){
  209. tupParaSet(&tupsendPara, DEFAULT_POC_PORT, pocRecv_cb,POC_TCP_THREAD_STACK);
  210. break;
  211. }else{
  212. PTTimerStart(ptPool, &ptTimer,1);//can be set fast
  213. PT_WAIT_UNTIL(pt, PTTimerIsExpired(&ptTimer));
  214. }
  215. }
  216. }
  217. if(ret==DOMAIN_OK){
  218. if(TUP_STATUS_WAIT != tupCStatus) tupCStatus=tryConnectTup(paras.pocServer.ip,TUP_TCP,&tupsendPara);
  219. switch(tupCStatus){
  220. case TUP_STATUS_TRUE:
  221. wlog_info("poc connect server ok");
  222. talking.tcpSocket=tupsendPara.fd;
  223. talking.conFailType.time=getSysTick();
  224. talking.netWork.tcp=1;
  225. break;
  226. case TUP_STATUS_FALSE:
  227. wlog_warn("poc connect server failed, retry");
  228. if(++talking.conFailType.count>=3) updateLineStatus(LINES_UN_CONNECT_IP, S_SET);
  229. break;
  230. case TUP_STATUS_WAIT:
  231. break;
  232. }
  233. }
  234. }else if(TUP_STATUS_WAIT==tupCStatus){
  235. if(tupsendPara.errno!=0){
  236. tupCStatus=TUP_STATUS_FALSE;
  237. }
  238. }
  239. }else{
  240. tupCStatus=TUP_STATUS_ONLINE;
  241. ticketVote(TICKET_PT_LOGINCON);
  242. }
  243. }else{
  244. ticketVote(TICKET_PT_LOGINCON);
  245. if(++printfCnt>=5){
  246. printfCnt=0;
  247. wlog_info("poc login is invalid");
  248. }
  249. }
  250. }
  251. PTTimerStart(ptPool, &ptTimer,100);//need set to 1 seconds
  252. PT_WAIT_UNTIL(pt, PTTimerIsExpired(&ptTimer));
  253. }
  254. PT_END(pt);
  255. }
  256. //poc login logic handler start...////////////////////////////////
  257. static T_BOOL pocLoginTimeOut(void){
  258. static T_UINT8 tick=0;
  259. if(++tick < 5) return FALSE;
  260. tick=0;
  261. return TRUE;
  262. }
  263. static void pocKeepAliveUdp(void){
  264. T_UINT8 value;
  265. if(talking.workIn_4G==TRUE) value=paras.udpHeartTick_4G;
  266. else value=paras.udpHeartTick_none_4G;
  267. if(talking.pocTupCnt % value != 0) return;
  268. wlog_info("udp keep alive:%d", value);
  269. udpAliveConnect();
  270. msgToOutter("+POC:WAKEUP\r\n");
  271. }
  272. static void pocKeepAliveTcp(void){
  273. T_UINT8 value;
  274. if(talking.pocTupCnt != 0) return;
  275. if(talking.workIn_4G==TRUE) value=talking.maxValue_4G;
  276. else value=talking.maxValue_none_4G;
  277. wlog_info("tcp keep alive:%d,%d", value,talking.pocTupCnt);
  278. pocTryTcpHeart(talking.tcpSocket);
  279. talking.tcpHeartCtl.counter=0;
  280. talking.tcpHeartCtl.hadSendOnePacket=1;
  281. }
  282. void pocTupCntCheck(void){
  283. T_UINT8 value;
  284. if(talking.workIn_4G==TRUE) value=talking.maxValue_4G;
  285. else value=talking.maxValue_none_4G;
  286. if(++talking.pocTupCnt >= value) talking.pocTupCnt=0;
  287. }
  288. //检查登陆任务是否空闲
  289. void isLoginIdle(void){
  290. if(0==talking.netWork.tcp) ticketDeVote(TICKET_PT_LOGIN);
  291. else{
  292. //如果已登陆,投票
  293. if(TCP_ONLINE_IDLE==talking.tcpLoginStatus || talking.pocTupCnt!=0) ticketVote(TICKET_PT_LOGIN);//pocTupCnt为0时不能休眠,因为要发心跳或建立链接
  294. else ticketDeVote(TICKET_PT_LOGIN);
  295. }
  296. }
  297. PT_THREAD (ptPocLoginTask(pt_timer_t *ptPool, struct pt *pt)){
  298. static pt_timer_t ptTimer;
  299. PT_BEGIN(pt);
  300. while(1){
  301. if(1==talking.netWork.tcp){
  302. switch(talking.tcpLoginStatus){
  303. case TCP_INIT:
  304. wlog_info("Try login");
  305. talking.accountError=FALSE;
  306. pocTryLogin(talking.tcpSocket,paras.psn, paras.pass);
  307. talking.tcpLoginStatus=TCP_LOGINING;
  308. break;
  309. case TCP_LOGIN_SUCC:
  310. wlog_info("Try query group");
  311. pocTryQueryGroup(talking.tcpSocket,G_NUM_MAX);
  312. talking.tcpLoginStatus=TCP_LOGINING;
  313. break;
  314. case TCP_QUERY_GRP_SUCC:
  315. wlog_info("Try join group");
  316. talking.loginAckAlready=FALSE;
  317. pocTryJoinGroup(talking.tcpSocket);
  318. talking.tcpLoginStatus=TCP_LOGINING;
  319. break;
  320. case TCP_JOIN_GRP_SUCC:
  321. wlog_info("----->Poc Online<-----");
  322. talking.tcpLoginStatus=TCP_ONLINE_IDLE;
  323. talking.outputInfoInterval=30;
  324. talking.pocTupCnt=0;//登陆成功后马上发心跳,尽快建立UDP通道
  325. break;
  326. case TCP_LOGINING:
  327. if(TRUE==pocLoginTimeOut()){
  328. wlog_warn("Login timeout, reset");
  329. talking.tcpLoginStatus=TCP_INIT;
  330. }
  331. break;
  332. case TCP_COMM_FAIL:
  333. wlog_error("Login status failed, retry");
  334. closeTalk();
  335. break;
  336. case TCP_ONLINE_IDLE:
  337. pocKeepAliveUdp();
  338. pocKeepAliveTcp();
  339. pocTupCntCheck();
  340. break;
  341. default:break;
  342. }
  343. }
  344. isLoginIdle();
  345. PTTimerStart(ptPool, &ptTimer,100);//need set to 1 seconds
  346. PT_WAIT_UNTIL(pt, PTTimerIsExpired(&ptTimer));
  347. }
  348. PT_END(pt);
  349. }
  350. void closeTalk(void){
  351. T_INT8 info[50];
  352. wlog_warn("close talk");
  353. updateLineStatus(LINES_ONLINE, S_CLEAR);
  354. talking.pttReqStatus=FALSE;
  355. talking.hasVoicePri=FALSE;
  356. // if(isPlayerIsOff()==FALSE || isRecordIsOff()==FALSE) pocSpkMicNotify(C_OFF, C_OFF);//off line will output info new add
  357. pocStopPlayer();
  358. pocStopRecord();
  359. if(TCP_ONLINE_IDLE==talking.tcpLoginStatus){
  360. pocTryLogout(talking.tcpSocket);
  361. snprintf(info, sizeof(info), "+POC:8200%08x\r\n", get_uid());
  362. msgToOutter(info);
  363. }
  364. talking.tcpLoginStatus=TCP_INIT;
  365. if(talking.tcpSocket!=0){
  366. userCloseSocket(&talking.tcpSocket);
  367. talking.tcpSocket=0;
  368. }
  369. talking.netWork.tcp=0;
  370. if(talking.udpSocket!=0){
  371. userCloseSocket(&talking.udpSocket);
  372. talking.udpSocket=0;
  373. }
  374. talking.udpHeartAckCnt=0;
  375. talking.pocTupCnt=0;
  376. talking.tcpHeartCtl.counter=0;
  377. talking.tcpHeartCtl.hadSendOnePacket=0;
  378. GroupListClear();
  379. UserListClear();
  380. msgQueueClear(Q_VOICEP);
  381. msgQueueClear(Q_VOICER);
  382. }
  383. void pocStartPlayer(void){
  384. PlyOpenNowApi();
  385. //sem_post(talking.semPlyRec);
  386. }
  387. void pocStartRecord(void){
  388. talking.recordStatus=RECORD_START;
  389. RecOpenNowApi();
  390. //sem_post(talking.semPlyRec);
  391. }
  392. void pocStopPlayer(void){
  393. PlyCloseNowApi();
  394. }
  395. void pocStopRecord(void){
  396. RecCloseNowApi();
  397. talking.recordStatus=RECORD_END;
  398. }
  399. void GroupListClear(void){
  400. T_UINT16 i;
  401. for(i=0;i<G_NUM_MAX;i++){
  402. talking.gInfo.gInfo[i].id=0;
  403. talking.gInfo.gInfo[i].memNum=0;
  404. memset(talking.gInfo.gInfo[i].name,0,sizeof(talking.gInfo.gInfo[i].name));
  405. }
  406. talking.gInfo.gIndex=0;
  407. talking.gInfo.g_numbers=0;
  408. }
  409. void UserListClear(void){
  410. T_UINT16 i;
  411. for(i=0;i<U_NUM_MAX;i++){
  412. talking.uInfo.uInfo[i].id=0;
  413. memset(talking.uInfo.uInfo[i].name,0,sizeof(talking.uInfo.uInfo[i].name));
  414. }
  415. talking.uInfo.u_numbers=0;
  416. }
  417. T_INT32 getPocMinCnt(void){
  418. T_INT32 value;
  419. if(talking.workIn_4G==TRUE) value=paras.udpHeartTick_4G;
  420. else value=paras.udpHeartTick_none_4G;
  421. value -= talking.pocTupCnt%30;
  422. return value;
  423. }
  424. void pocCntUpdate(T_INT32 value){
  425. talking.pocTupCnt += value;//下次起来就可以直接发心跳了
  426. if(talking.workIn_4G==TRUE) value=talking.maxValue_4G;
  427. else value=talking.maxValue_none_4G;
  428. if(talking.pocTupCnt>=value) talking.pocTupCnt=0;//要判断一下,否则会发两次UDP包
  429. }
  430. T_UID get_uid(void){return talking.uid;}
  431. T_GID get_gid(void){return talking.gid;}