//-------------------------------------------------------------------------------------------------- static void OnClientDisconnect ( le_msg_SessionRef_t sessionRef, void *contextPtr ) { Client_t *c; WakeupSource_t *ws; le_hashmap_It_Ref_t iter; // Find and remove client record from table c = to_Client_t(le_hashmap_Remove(PowerManager.clients, sessionRef)); LE_INFO("Client pid %d disconnected.", c->pid); // Find and remove all wakeup sources held for this client iter = le_hashmap_GetIterator(PowerManager.locks); while (LE_OK == le_hashmap_NextNode(iter)) { ws = (WakeupSource_t*)le_hashmap_GetValue(iter); if (ws->pid != c->pid) // Does not belong to this client, skip continue; // Release wakeup source if taken if (ws->taken) { LE_WARN("Releasing wakeup source '%s' on behalf of pid %d.", ws->name, ws->pid); le_pm_Relax((le_pm_WakeupSourceRef_t)ws->wsref); } // Delete wakeup source record, free memory LE_INFO("Deleting wakeup source '%s' on behalf of pid %d.", ws->name, ws->pid); le_hashmap_Remove(PowerManager.locks, ws->name); le_ref_DeleteRef(PowerManager.refs, ws->wsref); le_mem_Release(ws); } // Free client record le_mem_Release(c); return; }
//-------------------------------------------------------------------------------------------------- static void NewCallEventHandler ( pa_mcc_CallEventData_t* dataPtr ) { le_mcc_Call_t* callPtr = NULL; // Acquire wakeup source on first indication of call if (LE_MCC_EVENT_SETUP == dataPtr->event || LE_MCC_EVENT_ORIGINATING == dataPtr->event || LE_MCC_EVENT_INCOMING == dataPtr->event) { // Note: 3GPP calls have both SETUP and INCOMING states, so // this will warn on INCOMING state as a second "stay awake" le_pm_StayAwake(WakeupSource); } // Check if we have already an ongoing callPtr for this call callPtr = GetCallObject("", dataPtr->callId, true); if (callPtr == NULL) { // Call not in progress // check if a callPtr exists with the same number callPtr = GetCallObject(dataPtr->phoneNumber, -1, false); if (callPtr == NULL) { callPtr = CreateCallObject (dataPtr->phoneNumber, dataPtr->callId, dataPtr->event, dataPtr->terminationEvent, dataPtr->terminationCode); } callPtr->inProgress = true; } else { callPtr->event = dataPtr->event; callPtr->termination = dataPtr->terminationEvent; callPtr->terminationCode = dataPtr->terminationCode; // Update reference count UpdateReferenceCount(callPtr); } // Handle call state transition switch (dataPtr->event) { case LE_MCC_EVENT_TERMINATED: // Release wakeup source once call termination is processed le_pm_Relax(WakeupSource); callPtr->inProgress = false; break; default: break; } // Call the client's handler le_event_Report(CallStateEventId, &callPtr->callRef, sizeof(callPtr->callRef)); }