void AmB2BCalleeSession::onB2BEvent(B2BEvent* ev) { if(ev->event_id == B2BConnectLeg){ B2BConnectEvent* co_ev = dynamic_cast<B2BConnectEvent*>(ev); if (!co_ev) return; MONITORING_LOG3(getLocalTag().c_str(), "b2b_leg", getOtherId().c_str(), "to", co_ev->remote_party.c_str(), "ruri", co_ev->remote_uri.c_str()); dlg->setRemoteParty(co_ev->remote_party); dlg->setRemoteUri(co_ev->remote_uri); if (co_ev->relayed_invite) { AmSipRequest fake_req; fake_req.method = SIP_METH_INVITE; fake_req.cseq = co_ev->r_cseq; relayed_req[dlg->cseq] = fake_req; } AmMimeBody body(co_ev->body); try { updateLocalBody(body); } catch (const string& s) { relayError(SIP_METH_INVITE, co_ev->r_cseq, co_ev->relayed_invite, 500, SIP_REPLY_SERVER_INTERNAL_ERROR); throw; } int res = dlg->sendRequest(SIP_METH_INVITE, &body, co_ev->hdrs, SIP_FLAGS_VERBATIM); if (res < 0) { DBG("sending INVITE failed, relaying back error reply\n"); relayError(SIP_METH_INVITE, co_ev->r_cseq, co_ev->relayed_invite, res); if (co_ev->relayed_invite) relayed_req.erase(dlg->cseq); setStopped(); return; } saveSessionDescription(co_ev->body); // save CSeq of establising INVITE est_invite_cseq = dlg->cseq - 1; est_invite_other_cseq = co_ev->r_cseq; return; } AmB2BSession::onB2BEvent(ev); }
void AmB2BCallerSession::createCalleeSession() { AmB2BCalleeSession* callee_session = newCalleeSession(); if (NULL == callee_session) return; AmSipDialog* callee_dlg = callee_session->dlg; setOtherId(AmSession::getNewId()); callee_dlg->setLocalTag(getOtherId()); if (callee_dlg->getCallid().empty()) callee_dlg->setCallid(AmSession::getNewId()); callee_dlg->setLocalParty(dlg->getRemoteParty()); callee_dlg->setRemoteParty(dlg->getLocalParty()); callee_dlg->setRemoteUri(dlg->getLocalUri()); if (AmConfig::LogSessions) { INFO("Starting B2B callee session %s\n", callee_session->getLocalTag().c_str()); } MONITORING_LOG4(getOtherId().c_str(), "dir", "out", "from", callee_dlg->getLocalParty().c_str(), "to", callee_dlg->getRemoteParty().c_str(), "ruri", callee_dlg->getRemoteUri().c_str()); try { initializeRTPRelay(callee_session); } catch (...) { delete callee_session; throw; } AmSessionContainer* sess_cont = AmSessionContainer::instance(); sess_cont->addSession(getOtherId(),callee_session); callee_session->start(); }
int AmB2BCallerSession::relayEvent(AmEvent* ev) { if(getOtherId().empty() && !getStopped()){ bool create_callee = false; B2BSipEvent* sip_ev = dynamic_cast<B2BSipEvent*>(ev); if (sip_ev && sip_ev->forward) create_callee = true; else create_callee = dynamic_cast<B2BConnectEvent*>(ev) != NULL; if (create_callee) { createCalleeSession(); if (getOtherId().length()) { MONITORING_LOG(getLocalTag().c_str(), "b2b_leg", getOtherId().c_str()); } } } return AmB2BSession::relayEvent(ev); }
int gameInfoToServerMessage(AllGameInfo agi, ServerMessage *sm, int clientId){ /* 将游戏信息转换为特定的服务器消息 */ int num,otherNum; initServerMessage(sm); num = clientId -1; otherNum = getOtherId(clientId) -1; sm->clientId = clientId; strcpy(sm->playerCurPokerString, agi.playerCurPokerString[num]); strcpy(sm->playerPuttedPokerString, agi.playerPuttedPokerString[num]); strncpy(sm->playerPuttingPokerName, agi.playerPuttingPokerName[num], 2); sm->playerScore[0] = agi.playerScore[num]; sm->playerStat = agi.playerStat[num]; strcpy(sm->errorStr, agi.errorStr[num]); //otherCurNum strcpy(sm->rivalPuttedPokerString, agi.playerPuttedPokerString[otherNum]); sm->rivalCurPokerNum = countPokerStringNum(agi.playerCurPokerString[otherNum]); strncpy(sm->rivalPuttingPokerName, agi.playerPuttingPokerName[otherNum], 2); sm->playerScore[1] = agi.playerScore[otherNum]; return 0; }
void AmB2BCallerSession::onB2BEvent(B2BEvent* ev) { bool processed = false; if(ev->event_id == B2BSipReply){ AmSipReply& reply = ((B2BSipReplyEvent*)ev)->reply; if(getOtherId().empty()){ //DBG("Discarding B2BSipReply from other leg (other_id empty)\n"); DBG("B2BSipReply: other_id empty (" "reply code=%i; method=%s; callid=%s; from_tag=%s; " "to_tag=%s; cseq=%i)\n", reply.code,reply.cseq_method.c_str(),reply.callid.c_str(),reply.from_tag.c_str(), reply.to_tag.c_str(),reply.cseq); //return; } else if(getOtherId() != reply.from_tag){// was: local_tag DBG("Dialog mismatch! (oi=%s;ft=%s)\n", getOtherId().c_str(),reply.from_tag.c_str()); return; } DBG("%u %s reply received from other leg\n", reply.code, reply.reason.c_str()); switch(callee_status){ case NoReply: case Ringing: if (reply.cseq == invite_req.cseq) { if (reply.code < 200) { if ((!sip_relay_only) && (reply.code>=180 && reply.code<=183 && (!reply.body.empty()))) { // save early media SDP updateSessionDescription(reply.body); if (sip_relay_early_media_sdp) { if (reinviteCaller(reply)) { ERROR("re-INVITEing caller for early session failed - " "stopping this and other leg\n"); terminateOtherLeg(); terminateLeg(); break; } } } callee_status = Ringing; } else if(reply.code < 300){ callee_status = Connected; DBG("setting callee status to connected\n"); if (!sip_relay_only) { DBG("received 200 class reply to establishing INVITE: " "switching to SIP relay only mode, sending re-INVITE to caller\n"); sip_relay_only = true; AmSipReply n_reply = reply; if (n_reply.body.empty() && !established_body.empty()) { DBG("callee FR without SDP, using provisional response's (18x) one\n"); n_reply.body = established_body; } if (reinviteCaller(n_reply)) { ERROR("re-INVITEing caller failed - stopping this and other leg\n"); terminateOtherLeg(); terminateLeg(); } } } else { // DBG("received %i from other leg: other_id=%s; reply.local_tag=%s\n", // reply.code,other_id.c_str(),reply.local_tag.c_str()); // TODO: terminated my own leg instead? (+ clear_other()) terminateOtherLeg(); } processed = onOtherReply(reply); } break; default: DBG("reply from callee: %u %s\n",reply.code,reply.reason.c_str()); break; } } if (!processed) AmB2BSession::onB2BEvent(ev); }
int playerPutPoker(AllGameInfo *agi, char *cmd[]){ /* player put poker */ char *p,*q,*s; char buf[10]; char errorStr[MAX_MESSAGE+1]; int clientId; int num,otherNum; char *pokerName; pokerName = cmd[2]; /* 在这个函数里不知道怎么会把agi->errorStr改变 */ clientId = getClientId(cmd[0]); num = clientId - 1; /* 检测是否轮到 clientId 出牌 */ if(agi->playerStat[num] != 1){ errorNo = CLIENT_PLA_TURN_ERROR; strcpy(agi->errorStr[num], "没有轮到你出牌"); return -1; } /* 检测clientId 有没有 pokerName */ s = strstr(agi->playerCurPokerString[num], pokerName); if(s == NULL){ errorNo = CLIENT_POK_NON_ERROR; sprintf(errorStr, "你没有‘%2s’牌",pokerName); strcpy(agi->errorStr[num], errorStr); return -1; } /* 储存要出的牌 */ q = buf; p = s; while(*p != ' '){ *q++ = *p++; } *q++ = ' '; /* 保持序列的一致性:t1 t3 d3 */ *q = '\0'; otherNum = getOtherId(clientId) - 1; /* 出过两张牌后,清空 */ if(clearCard == 2){ clearCard =0; memset(agi->playerPuttingPokerName[otherNum], 0, 6); } if(!strcmp(agi->playerPuttingPokerName[otherNum], "")){ /* 对方没出牌 */ strcpy(agi->playerPuttingPokerName[num], buf); strcat(agi->playerPuttingPokerName[num], "1"); clearCard++; }else{ /* 对方已出牌 */ strcpy(agi->playerPuttingPokerName[num], buf); strcat(agi->playerPuttingPokerName[num], "2"); clearCard++; } /* 比较牌的大小 */ if(clearCard == 2){ comparePutingCard(agi); } /* 删除打出的牌 */ while(*s){ /* 可能有问题,证明没问题 */ *s = *(s+3); s++; } /* 将删除的牌加入出过的牌中 */ strcat(agi->playerPuttedPokerString[num],buf); /* 改变玩家状态 */ if(clearCard != 2){ changePlayerStat(agi->playerStat); } if(clearCard == 2) pkResult(agi); strcpy(agi->errorStr[num], ""); return 0; }