43 class OpalSkinnyConnection;
58 const char *prefix =
"sccp"
63 virtual ~OpalSkinnyEndPoint();
94 virtual void NewIncomingConnection(
128 const PString & party,
130 unsigned int options,
147 virtual OpalSkinnyConnection * CreateConnection(
149 PhoneDevice & client,
150 unsigned callIdentifier,
151 const PString & dialNumber,
153 unsigned int options,
160 enum { DefaultDeviceType = 30016 };
165 const PString & server,
166 const PString & name,
167 unsigned deviceType = DefaultDeviceType
176 PhoneDevice * GetPhoneDevice(
178 )
const {
return m_phoneDevices.GetAt(name); }
180 PArray<PString> GetPhoneDeviceNames()
const {
return m_phoneDevices.GetKeys(); }
186 class PhoneDevice :
public PObject
188 PCLASSINFO(PhoneDevice, PObject);
190 PhoneDevice(OpalSkinnyEndPoint & ep,
const PString & name,
unsigned deviceType);
192 virtual void PrintOn(ostream & strm)
const;
194 bool Start(
const PString & server);
198 bool SendSkinnyMsg(
const SkinnyMsg & msg);
200 const PString & GetName()
const {
return m_name; }
201 const PString & GetStatus()
const {
return m_status; }
205 void HandleTransport();
206 bool SendRegisterMsg();
208 template <
class MSG>
bool OnReceiveMsg(
const MSG & msg)
210 PTRACE(3,
"Skinny",
"Received " << msg);
211 return m_endpoint.OnReceiveMsg(*
this, msg);
214 OpalSkinnyEndPoint & m_endpoint;
216 unsigned m_deviceType;
218 PTimeInterval m_delay;
222 friend class OpalSkinnyEndPoint;
223 friend class OpalSkinnyConnection;
228 class SkinnyMsg :
public PObject
230 PCLASSINFO(SkinnyMsg, PObject);
232 SkinnyMsg(uint32_t
id, PINDEX len);
233 void Construct(
const PBYTEArray & pdu);
236 uint32_t GetID()
const {
return m_messageId; }
238 const BYTE * GetPacketPtr()
const {
return (
const BYTE *)&m_length; }
239 PINDEX GetPacketLen()
const {
return m_length +
sizeof(m_length) +
sizeof(m_headerVersion); }
243 PUInt32l m_headerVersion;
244 PUInt32l m_messageId;
248 #define OPAL_SKINNY_MSG(cls, id, vars) \
249 class cls : public SkinnyMsg \
251 PCLASSINFO(cls, SkinnyMsg); \
254 cls() : SkinnyMsg(ID, sizeof(*this)) { } \
255 cls(const PBYTEArray & pdu) : SkinnyMsg(ID, sizeof(*this)) { Construct(pdu); } \
258 virtual bool OnReceiveMsg(PhoneDevice & client, const cls & msg)
260 OPAL_SKINNY_MSG(KeepAliveMsg, 0x0000,
264 OPAL_SKINNY_MSG(KeepAliveAckMsg, 0x0100,
267 OPAL_SKINNY_MSG(RegisterMsg, 0x0001,
268 enum { MaxNameSize = 15 };
269 char m_deviceName[MaxNameSize+1];
273 PUInt32l m_deviceType;
274 PUInt32l m_maxStreams;
276 char m_macAddress[12];
278 virtual void PrintOn(ostream & strm)
const { strm << GetClass() <<
" device=" << m_deviceName <<
" type=" << m_deviceType <<
" streams=" << m_maxStreams <<
" ip=" << PIPAddress(m_ip); }
281 OPAL_SKINNY_MSG(RegisterAckMsg, 0x0081,
282 PUInt32l m_keepAlive;
283 char m_dateFormat[6];
285 PUInt32l m_secondaryKeepAlive;
288 virtual void PrintOn(ostream & strm)
const { strm << GetClass() <<
" keepAlive=" << m_keepAlive; }
291 OPAL_SKINNY_MSG(RegisterRejectMsg, 0x009d,
292 char m_errorText[32];
295 OPAL_SKINNY_MSG(UnregisterMsg, 0x0027,
298 OPAL_SKINNY_MSG(UnregisterAckMsg, 0x0118,
302 OPAL_SKINNY_MSG(PortMsg, 0x0002,
305 virtual void PrintOn(ostream & strm)
const { strm << GetClass() <<
' ' << m_port; }
308 OPAL_SKINNY_MSG(CapabilityRequestMsg, 0x009B,
311 OPAL_SKINNY_MSG(CapabilityResponseMsg, 0x0010,
316 PUInt16l m_maxFramesPerPacket;
320 virtual void PrintOn(ostream & strm)
const { strm << GetClass() <<
' ' << m_count <<
" codecs"; }
322 void SetCount(PINDEX count)
325 m_length = m_length - (PARRAYSIZE(m_capability) - count) *
sizeof(Info);
329 P_DECLARE_STREAMABLE_ENUM(CallStates,
343 eStateCallRemoteMultiline,
346 OPAL_SKINNY_MSG(CallStateMsg, 0x0111,
348 PUInt32l m_lineInstance;
349 PUInt32l m_callIdentifier;
352 __inline CallStates GetState()
const {
return (CallStates)(uint32_t)m_state; }
353 virtual void PrintOn(ostream & strm)
const { strm << GetClass() <<
' ' << GetState() <<
" line=" << m_lineInstance <<
" call=" << m_callIdentifier; }
356 P_DECLARE_STREAMABLE_ENUM(CallType,
362 OPAL_SKINNY_MSG(CallInfoMsg, 0x008f,
363 char m_callingPartyName[40];
364 char m_callingPartyNumber[24];
365 char m_calledPartyName[40];
366 char m_calledPartyNumber[24];
367 PUInt32l m_lineInstance;
368 PUInt32l m_callIdentifier;
370 char m_originalCalledPartyName[40];
371 char m_originalCalledPartyNumber[24];
372 char m_lastRedirectingPartyName[40];
373 char m_lastRedirectingPartyNumber[24];
374 PUInt32l m_originalCalledPartyRedirectReason;
375 PUInt32l m_lastRedirectingReason;
376 char m_callingPartyVoiceMailbox[24];
377 char m_calledPartyVoiceMailbox[24];
378 char m_originalCalledPartyVoiceMailbox[24];
379 char m_lastRedirectingVoiceMailbox[24];
380 PUInt32l m_callInstance;
381 PUInt32l m_callSecurityStatus;
382 PUInt32l m_partyPIRestrictionBits;
384 __inline CallType GetType()
const {
return (CallType)(uint32_t)m_callType; }
385 virtual void PrintOn(ostream & strm)
const { strm << GetClass() <<
' ' << GetType() <<
" line=" << m_lineInstance <<
" call=" << m_callIdentifier; }
395 OPAL_SKINNY_MSG(SetRingerMsg, 0x0085,
398 PUInt32l m_lineInstance;
399 PUInt32l m_callIdentifier;
401 __inline RingType GetType()
const {
return (RingType)(uint32_t)m_ringType; }
402 __inline
bool IsForever()
const {
return m_ringMode == 1; }
403 virtual void PrintOn(ostream & strm)
const { strm << GetClass() <<
' ' << GetType() <<
" mode=" << m_ringMode <<
" line=" << m_lineInstance <<
" call=" << m_callIdentifier; }
406 OPAL_SKINNY_MSG(OffHookMsg, 0x0006,
407 PUInt32l m_lineInstance;
408 PUInt32l m_callIdentifier;
410 virtual void PrintOn(ostream & strm)
const { strm << GetClass() <<
" line=" << m_lineInstance <<
" call=" << m_callIdentifier; }
413 OPAL_SKINNY_MSG(OnHookMsg, 0x0007,
414 PUInt32l m_lineInstance;
415 PUInt32l m_callIdentifier;
417 virtual void PrintOn(ostream & strm)
const { strm << GetClass() <<
" line=" << m_lineInstance <<
" call=" << m_callIdentifier; }
427 eToneCallWaiting = 0x2d,
430 OPAL_SKINNY_MSG(StartToneMsg, 0x0082,
433 PUInt32l m_lineInstance;
434 PUInt32l m_callIdentifier;
436 __inline Tones GetType()
const {
return (Tones)(uint32_t)m_tone; }
437 virtual void PrintOn(ostream & strm)
const { strm << GetClass() <<
' ' << GetType() <<
" line=" << m_lineInstance <<
" call=" << m_callIdentifier; }
440 OPAL_SKINNY_MSG(StopToneMsg, 0x0083,
441 PUInt32l m_lineInstance;
442 PUInt32l m_callIdentifier;
444 virtual void PrintOn(ostream & strm)
const { strm << GetClass() <<
" line=" << m_lineInstance <<
" call=" << m_callIdentifier; }
447 OPAL_SKINNY_MSG(KeyPadButtonMsg, 0x0003,
449 PUInt32l m_lineInstance;
450 PUInt32l m_callIdentifier;
452 virtual void PrintOn(ostream & strm)
const { strm << GetClass() <<
" \'" << m_button<<
"' line=" << m_lineInstance <<
" call=" << m_callIdentifier; }
455 P_DECLARE_STREAMABLE_ENUM(SoftKeyEvents,
463 eSoftKeyCfwdNoAnswer,
474 eSoftKeyGrpCallPickup,
478 OPAL_SKINNY_MSG(SoftKeyEventMsg, 0x0026,
480 PUInt32l m_lineInstance;
481 PUInt32l m_callIdentifier;
483 __inline SoftKeyEvents GetEvent()
const {
return (SoftKeyEvents)(uint32_t)m_event; }
484 virtual void PrintOn(ostream & strm)
const { strm << GetClass() <<
' ' << GetEvent() <<
" line=" << m_lineInstance <<
" call=" << m_callIdentifier; }
487 OPAL_SKINNY_MSG(OpenReceiveChannelMsg, 0x0105,
488 PUInt32l m_callIdentifier;
489 PUInt32l m_passThruPartyId;
490 PUInt32l m_msPerPacket;
491 PUInt32l m_payloadCapability;
492 PUInt32l m_echoCancelType;
493 PUInt32l m_g723Bitrate;
496 virtual void PrintOn(ostream & strm)
const { strm << GetClass() <<
" call=" << m_callIdentifier; }
499 OPAL_SKINNY_MSG(OpenReceiveChannelAckMsg, 0x0022,
504 PUInt32l m_passThruPartyId;
505 virtual void PrintOn(ostream & strm)
const { strm << GetClass() <<
' ' << PIPAddress(m_ip) <<
':' << m_port; }
508 OPAL_SKINNY_MSG(CloseReceiveChannelMsg, 0x0106,
509 PUInt32l m_callIdentifier;
510 PUInt32l m_passThruPartyId;
511 PUInt32l m_conferenceId2;
513 virtual void PrintOn(ostream & strm)
const { strm << GetClass() <<
" call=" << m_callIdentifier; }
516 OPAL_SKINNY_MSG(StartMediaTransmissionMsg, 0x008a,
517 PUInt32l m_callIdentifier;
518 PUInt32l m_passThruPartyId;
522 PUInt32l m_msPerPacket;
523 PUInt32l m_payloadCapability;
524 PUInt32l m_precedence;
525 PUInt32l m_silenceSuppression;
526 PUInt32l m_maxFramesPerPacket;
527 PUInt32l m_g723Bitrate;
530 virtual void PrintOn(ostream & strm)
const { strm << GetClass() <<
" call=" << m_callIdentifier <<
' ' << PIPAddress(m_ip) <<
':' << m_port; }
533 OPAL_SKINNY_MSG(StopMediaTransmissionMsg, 0x008b,
534 PUInt32l m_callIdentifier;
535 PUInt32l m_passThruPartyId;
536 PUInt32l m_conferenceId2;
538 virtual void PrintOn(ostream & strm)
const { strm << GetClass() <<
" call=" << m_callIdentifier; }
547 PSafePtr<OpalSkinnyConnection> GetSkinnyConnection(
const PhoneDevice & client, uint32_t callIdentifier, PSafetyMode mode = PSafeReadWrite);
548 template <
class MSG>
bool DelegateMsg(
const PhoneDevice & client,
const MSG & msg);
550 typedef PDictionary<PString, PhoneDevice> PhoneDeviceDict;
551 PhoneDeviceDict m_phoneDevices;
552 PMutex m_phoneDevicesMutex;
566 OpalSkinnyConnection(
568 OpalSkinnyEndPoint & ep,
569 OpalSkinnyEndPoint::PhoneDevice & client,
570 unsigned callIdentifier,
571 const PString & dialNumber,
653 virtual bool OnReceiveMsg(
const OpalSkinnyEndPoint::CallStateMsg & msg);
654 virtual bool OnReceiveMsg(
const OpalSkinnyEndPoint::CallInfoMsg & msg);
655 virtual bool OnReceiveMsg(
const OpalSkinnyEndPoint::SetRingerMsg & msg);
656 virtual bool OnReceiveMsg(
const OpalSkinnyEndPoint::OpenReceiveChannelMsg & msg);
657 virtual bool OnReceiveMsg(
const OpalSkinnyEndPoint::CloseReceiveChannelMsg & msg);
658 virtual bool OnReceiveMsg(
const OpalSkinnyEndPoint::StartMediaTransmissionMsg & msg);
659 virtual bool OnReceiveMsg(
const OpalSkinnyEndPoint::StopMediaTransmissionMsg & msg);
665 void SetFromIdMediaType(
const OpalMediaType & mediaType, uint32_t
id);
668 OpalSkinnyEndPoint & m_endpoint;
669 OpalSkinnyEndPoint::PhoneDevice & m_client;
671 uint32_t m_lineInstance;
672 uint32_t m_callIdentifier;
673 PString m_alertingType;
674 bool m_needSoftKeyEndcall;
683 template <
class MSG>
bool OpalSkinnyEndPoint::DelegateMsg(
const PhoneDevice & client,
const MSG & msg)
685 PSafePtr<OpalSkinnyConnection> connection = GetSkinnyConnection(client, msg.m_callIdentifier);
686 PTRACE_CONTEXT_ID_PUSH_THREAD(connection);
687 return connection == NULL || connection->OnReceiveMsg(msg);
691 #endif // OPAL_SKINNY
693 #endif // OPAL_SKINNY_H