dcch may be SDCCH or FACCH. This does not return until the channel is released.
| 969 | // dcch may be SDCCH or FACCH. |
| 970 | // This does not return until the channel is released. |
| 971 | void L3DCCHLoop(L3LogicalChannel*dcch, L3Frame *frame) |
| 972 | { |
| 973 | LOG(INFO) <<"DCCH LOOP OPEN "<<dcch; |
| 974 | try { |
| 975 | // We must not reset the channel state when opened because during a channel reassignment the new channel |
| 976 | // already has an attached MMContext. |
| 977 | assert(frame); |
| 978 | Primitive prim = frame->primitive(); |
| 979 | delete frame; |
| 980 | |
| 981 | dcch->chanSetState(L3LogicalChannel::chEstablished); |
| 982 | switch (prim) { |
| 983 | case ESTABLISH: |
| 984 | break; |
| 985 | case HANDOVER_ACCESS: |
| 986 | ProcessHandoverAccess(dcch); |
| 987 | // If the handover fails, it sets the chState such that the loop below will return immediately, |
| 988 | // so we can just break here. |
| 989 | break; |
| 990 | default: |
| 991 | assert(0); // Caller prevented anything else. |
| 992 | } |
| 993 | |
| 994 | switch (dcch->chtype()) { |
| 995 | case SDCCHType: |
| 996 | L3SDCCHLoop(dcch); |
| 997 | break; |
| 998 | case FACCHType: |
| 999 | l3CallTrafficLoop(dcch); |
| 1000 | break; |
| 1001 | default: |
| 1002 | assert(0); |
| 1003 | } |
| 1004 | devassert(dcch->mChState != L3LogicalChannel::chIdle); // This would be a bug. |
| 1005 | } catch (exception &e) { |
| 1006 | LOG(ERR) << "exception "<<e.what() << " " << typeid(&e).name(); |
| 1007 | } catch (...) { |
| 1008 | LOG(ERR) << "unrecognized exception, channel reset"; |
| 1009 | } |
| 1010 | WATCHINFO("DCCH LOOP EXIT " << dcch); |
| 1011 | |
| 1012 | // Always reset, even though the MMContext is shared between L3LogicalChannels during channel reassignment; |
| 1013 | // we now have a refcnt in the MMContext so this is bullet proof destruction. |
| 1014 | dcch->L3LogicalChannelReset(); |
| 1015 | switch (dcch->mChState) { |
| 1016 | case L3LogicalChannel::chRequestRelease: |
| 1017 | // The RELEASE primitive will block up to 30 seconds, so we NEVER EVER send it from anywhere but right here. |
| 1018 | // To release the channel, set the channel state to chReleaseRequest and let it come here to release the channel. |
| 1019 | // FIXME: Actually, LAPDm blocks in this forever until it gets the next ESTABLISH, so this is where the serviceloop really waits. |
| 1020 | dcch->l3sendp(RELEASE); // WARNING! This must be the only place in L3 that sends this primitive. |
| 1021 | break; |
| 1022 | case L3LogicalChannel::chRequestHardRelease: |
| 1023 | dcch->l3sendp(HARDRELEASE); |
| 1024 | break; |
| 1025 | default: break; |
| 1026 | } |
| 1027 | LOG(DEBUG) <<"CLOSE "<<dcch << " dump all:" <<gMMLayer.printMMInfo(); |
| 1028 |
no test coverage detected