private void DevLink_Received_CallBack(uint pbxh, StringBuilder rawDevLink) // CallEvent { // TODO: TRY - CATCH DEBUGLogger.WriteThreadInfo("DevLink_Received_CallBack"); DEBUGLogger.WriteLine("pbxh=" + pbxh + "; info=" + rawDevLink); _rawDevLinkQueue.Enqueue(new DevLinkMessage() { IpAddress = IpAddress, RawDevLink = rawDevLink.ToString(), SiteId = _iPOID }); // Make thread-safe: since this method is a CallBack, it will be called by Avaya's DevLink code // in its's thread, which will be different from any of the possible subscriber's threads. // http://broadcast.oreilly.com/2010/09/understanding-c-raising-events.html var devLinkRecieved_threadSafe = DevLinkRecieved; // Multi-cast delegates are immutable, so whatever happens to DevLinkRecieved from here on will NOT affect devLinkRecieved_threadSafe if (devLinkRecieved_threadSafe != null) { devLinkRecieved_threadSafe(this, new DevLinkEventArgs((int)pbxh, rawDevLink.ToString())); // NOTE: // When an event fires, all of the registered handlers execute on the same thread (the one that raised the event - // in our case - the thread belongs to Avaya's DevLink!). // There's no built-in facility for events to fire on multiple threads. // http://stackoverflow.com/questions/3480036/multiple-threads-subscribing-same-event } }
private void Process() { DEBUGLogger.WriteThreadInfo("Process"); _handleDelta2Event = DevLink_Received_CallBack; /*This routine may return:- * 0 = DEVLINK_SUCCESS * 1 = DEVLINK_UNSPECIFIEDFAIL - Returned in the event of an error. * 2 = DEVLINK_LICENCENOTFOUND - If no CTI license is activated on the IP Office system. */ long iRet = DLRegisterType2CallDeltas((uint)_iPOID, _handleDelta2Event // DLCALLLOGEVENT /* (pbxh, rawDevLink) => { lock (thisLock) * if (default(EventHandler<DevLinkEventArgs>) != DevLinkRecieved) * { * DevLinkRecieved(this, new DevLinkEventArgs(pbxh, rawDevLink)); * } } */ ); DEBUGLogger.WriteLine("DLRegisterType2CallDeltas return value = " + iRet); }
/// <summary> /// DLOpen callback /// </summary> /// <param name="pbxh"></param> /// <param name="comms_state"></param> /// <param name="parm1"></param> private void DevLink_Connection_CallBack(uint pbxh, int comms_state, int parm1) // oCommsEvent CommEvent { DEBUGLogger.WriteThreadInfo("DevLink_Connection_CallBack"); // TODO: TRY - CATCH DEBUGLogger.WriteLine("DevLink_Connection_CallBack: iPOID = " + pbxh + "; comms_state = " + comms_state + "; parm1 = " + parm1); if (_ignoreConnectionCallback) { return; // Whatever! } lock (_connectionLock) { if (_ignoreConnectionCallback) { // It is too late, we have already given up on this method returning! DEBUGLogger.WriteLine("DevLink_Connection_CallBack: Too late, the connection callback result (comms_state=" + comms_state + "; parm1=" + parm1 + ") is being ignored."); return; } switch ((ConnectionResponse)comms_state) { // Communications established. This occurs either after the initial call to DLOpen(), // or after the system unit has come back on-line after being powered off or rebooted. // TODO: does the above mean that this method will be called again if the system is rebooted...?? Think of how to handle this case! case ConnectionResponse.DEVLINK_COMMS_OPERATIONAL_0: { ConnectionState = ConnectionStates.Connected; // OK, we're done here, notify the main thread: // TODO: what if this happens before the WaitOne call? OK I guess??? _waitConnectionOrTimeoutHandle.Set(); return; } // No response from system unit. This occurs either (1) after the initial call to DLOpen(), or // (2) if the system unit is powered off/rebooted, or (3) if network problems prevent communications. case ConnectionResponse.DEVLINK_COMMS_NORESPONSE_1: { // TODO: LOG a message, and wait more for possible recovery. ConnectionState = ConnectionStates.Failed; return; } // Reserved for future use OR incorrect system password specified (????) case ConnectionResponse.DEVLINK_COMMS_REJECTED_2: { _connectionCallbackMessage = "Received response DEVLINK_COMMS_REJECTED - Reserved for future use! Do we have to implement this case too?"; break; } // Packets were generated by IPO, but were not received by DevLink. // This can occur either because the IPO is under heavy load (IPPO always prioritizes data routing and call handling above CTI events // - parm1 contains the number of packets missed) // or because the application using DevLink did not return from a callback quickly enough. // Applications should ensure that they do not take more than 100 milliseconds to process events. case ConnectionResponse.DEVLINK_COMMS_MISSEDPACKETS_3: { _connectionCallbackMessage = "There are " + parm1 + " lost packets! IPO may be under heavy load. Ensure that it takes no more than 100 ms to process events!"; break; } default: _connectionCallbackMessage = "Ooops, got unexpected result! comms_state = " + comms_state; break; } // Hmm, we were not able to connect successfully. We WON'T call _waitConnectionOrTimeoutHandle.Set() now, to give it some more time/chance to connect till the timeout. ConnectionState = ConnectionStates.Failed; } }