void XCCHL1Encoder::writeHighSide(const L2Frame& frame) { switch (frame.primitive()) { case DATA: // En,.ode and send data. if (!active()) { LOG(INFO) << "XCCHL1Encoder::writeHighSide sending on non-active channel"; } resync(); sendFrame(frame); break; case ESTABLISH: // Open both sides of the link. // The phone is waiting to see the idle pattern. open(); if (sibling()) sibling()->open(); return; case RELEASE: // Normally, we get here after a DISC-DM handshake in L2. // Close both sides of the link, knowing that the phone will do the same. close(); if (sibling()) sibling()->close(); break; case ERROR: // If we got here, it means the link failed in L2 after several ack timeouts. // Close the tx side and just let the receiver L1 time out on its own. // Otherwise, we risk recycling the channel while the phone's still active. close(); break; default: LOG(ERROR) << "unhandled primitive " << frame.primitive() << " in L2->L1"; assert(0); } }
void SACCHLogicalChannel::writeToL1(const L2Frame& frame) { // The SAP may or may not be present, depending on the channel type. OBJLOG(DEBUG) << frame; switch (frame.primitive()) { case L2_DATA: mL1->writeHighSide(frame); break; default: OBJLOG(ERR) << "unhandled primitive " << frame.primitive() << " in L2->L1"; devassert(0); } }
void L2SAPMux::sapWriteFromL1(const L2Frame& frame) { OBJLOG(DEBUG) << frame; unsigned sap; // (pat) Add switch to validate upstream primitives. The upstream only generates a few primitives; // the rest are created in L2LAPDm. switch (frame.primitive()) { case L2_DATA: sap = frame.SAPI(); assert(sap == SAPI0 || sap == SAPI3); if (mL2[sap]) { mL2[sap]->l2dlWriteLowSide(frame); } else { LOG(WARNING) << "received DATA for unsupported"<<LOGVAR(sap); } return; case PH_CONNECT: // All this does is fully reset LAPDm; copy it out to every SAP. for (int s = 0; s <= 3; s++) { if (mL2[s]) mL2[s]->l2dlWriteLowSide(frame); // Note: the frame may have the wrong SAP in it, but LAPDm doesnt care. } return; default: // If you get this assertion, make SURE you know what will happen upstream to that primitive. devassert(0); return; // make g++ happy. } }
void L2LAPDm::writeL1Ack(const L2Frame& frame) { // Caller should hold mLock. // GSM 04.06 5.4.4.2 OBJLOG(DEEPDEBUG) <<"L2LAPDm::writeL1Ack " << frame; frame.copyTo(mSentFrame); mSentFrame.primitive(frame.primitive()); writeL1(frame); mT200.set(); }
void LoopbackSAPMux::writeHighSide(const L2Frame& frame) { OBJLOG(DEBUG) << "Loopback " << frame; // Substitute primitive L2Frame newFrame(frame); unsigned SAPI = frame.SAPI(); switch (frame.primitive()) { case ERROR: SAPI=0; break; case RELEASE: return; default: break; } // Because this is a test fixture, as assert here. // If this were not a text fixture, we would print a warning // and ignore the frame. assert(mUpstream[SAPI]); ScopedLock lock(mLock); mUpstream[SAPI]->writeLowSide(newFrame); }
void SAPMux::writeLowSide(const L2Frame& frame) { OBJLOG(DEBUG) << frame.SAPI() << " " << frame; unsigned SAPI = frame.SAPI(); bool data = frame.primitive()==DATA; if (data && (!mUpstream[SAPI])) { LOG(WARNING) << "received DATA for unsupported SAP " << SAPI; return; } if (data) { mUpstream[SAPI]->writeLowSide(frame); } else { // If this is a non-data primitive, copy it out to every SAP. for (int i=0; i<4; i++) { if (mUpstream[i]) mUpstream[i]->writeLowSide(frame); } } }
void L2LogicalChannel::writeLowSide(const L2Frame& frame) { // If this is the first good frame of a new transaction, // stop T3101 and tell L2 we're alive down here. if (mT3101.active()) { mT3101.reset(); // Inform L3 that we are alive down here. // This does not block; goes to a InterthreadQueue L2LAPdm::mL1In sapWriteFromL1(L2Frame(PH_CONNECT)); } switch (frame.primitive()) { case HANDOVER_ACCESS: // Only send this on SAPI 0. writeToL3(new L3Frame(SAPI0,HANDOVER_ACCESS)); break; default: sapWriteFromL1(frame); break; } }