(pat) This is BS2 which has received a request from BS1 to transfer the MS from BS1 to BS2. Manufacture a TransactionEntry and SIPEngine from the peering message.
| 302 | // (pat) This is BS2 which has received a request from BS1 to transfer the MS from BS1 to BS2. |
| 303 | // Manufacture a TransactionEntry and SIPEngine from the peering message. |
| 304 | void PeerInterface::processHandoverRequest(const struct sockaddr_in* peer, const char* message) |
| 305 | { |
| 306 | // This is "Handover Request" in the ladder diagram; we are "BS2" accepting it. |
| 307 | assert(message); |
| 308 | |
| 309 | unsigned oldTransID; // (pat) tran on BS1 that wants to come to BS2. |
| 310 | if (!sscanf(message,"REQ HANDOVER %u ", &oldTransID)) { |
| 311 | LOG(ALERT) << "cannot parse peering message " << message; |
| 312 | return; |
| 313 | } |
| 314 | |
| 315 | // Break message into space-delimited tokens, stuff into a SimpleKeyValue and then unpack it. |
| 316 | SimpleKeyValue params; |
| 317 | params.addItems(message); |
| 318 | const char* IMSI = params.get("IMSI"); |
| 319 | GSM::L3MobileIdentity mobileID = GSM::L3MobileIdentity(IMSI); |
| 320 | |
| 321 | // find existing transaction record if this is a duplicate REQ HANDOVER |
| 322 | Control::TranEntry* transaction = gNewTransactionTable.ttFindHandoverOther(mobileID, oldTransID); |
| 323 | |
| 324 | // and the channel that goes with it |
| 325 | GSM::L2LogicalChannel* chan = NULL; |
| 326 | unsigned horef; |
| 327 | |
| 328 | // if this is the first REQ HANDOVER |
| 329 | if (!transaction) { |
| 330 | WATCH(Utils::timestr() << " Peering recv:"<<message); |
| 331 | |
| 332 | LOG(INFO) << "initial REQ HANDOVER for " << mobileID << " " << oldTransID; |
| 333 | |
| 334 | // Get a channel allocation. |
| 335 | // For now, we are assuming a full-rate channel. |
| 336 | // And check gBTS.hold() |
| 337 | time_t start = time(NULL); |
| 338 | if (!gBTS.hold()) { chan = gBTS.getTCH(); } // (pat) Starts T3101. Better finish before it expires. |
| 339 | LOG(DEBUG) << "getTCH took " << (time(NULL) - start) << " seconds"; |
| 340 | |
| 341 | // FIXME -- Somehow, getting from getTCH above to the test below can take several seconds. |
| 342 | // FIXME -- #797. |
| 343 | |
| 344 | // If getTCH took so long that there's too little time left in T3101, ignore this REQ and get the next one. |
| 345 | if (chan && chan->SACCH()->debugGetL1()->decoder()->debug3101remaining() < 1000) { |
| 346 | LOG(NOTICE) << "handover TCH allocation took too long; risk of T3101 timeout; trying again"; |
| 347 | chan->l2sendp(HARDRELEASE); // (pat) added 9-6-2013 |
| 348 | return; |
| 349 | } |
| 350 | |
| 351 | // If there's no channel available, send failure. |
| 352 | if (!chan) { |
| 353 | LOG(CRIT) << "congestion, incoming handover request denied"; |
| 354 | char rsp[50]; |
| 355 | // RR Cause 101 "cell allocation not available" |
| 356 | // GSM 04.08 10.5.2.31 |
| 357 | sprintf(rsp,"RSP HANDOVER %u 101", oldTransID); |
| 358 | sendMessage(peer,rsp); |
| 359 | return; |
| 360 | } |
| 361 |
nothing calls this directly
no test coverage detected