1 /*
2  * h460p.cxx
3  *
4  * H460 Presence class.
5  *
6  * h323plus library
7  *
8  * Copyright (c) 2008 ISVO (Asia) Pte. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.1 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Alternatively, the contents of this file may be used under the terms
16  * of the General Public License (the  "GNU License"), in which case the
17  * provisions of GNU License are applicable instead of those
18  * above. If you wish to allow use of your version of this file only
19  * under the terms of the GNU License and not to allow others to use
20  * your version of this file under the MPL, indicate your decision by
21  * deleting the provisions above and replace them with the notice and
22  * other provisions required by the GNU License. If you do not delete
23  * the provisions above, a recipient may use your version of this file
24  * under either the MPL or the GNU License."
25  *
26  * Software distributed under the License is distributed on an "AS IS"
27  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
28  * the License for the specific language governing rights and limitations
29  * under the License.
30  *
31  *
32  * The Initial Developer of the Original Code is ISVO (Asia) Pte. Ltd.
33  *
34  * Contributor(s): Many thanks to Simon Horne.
35  *
36  * $Revision: 21004 $
37  * $Author: rjongbloed $
38  * $Date: 2008-09-16 02:08:56 -0500 (Tue, 16 Sep 2008) $
39  */
40 
41 #include <ptlib.h>
42 
43 #include <opal/buildopts.h>
44 
45 #include <h323/h323pdu.h>
46 #include <h460/h460p.h>
47 
48 
49 #if OPAL_H460
50 
51 static struct {
52   unsigned id;
53   int     notification;
54   int     subscription;
55   int     instruction;
56   int     identifier;
57   int     cryptoTokens;
58 } PresenceMessage_attributes[] = {
59 //messageId 									Notification	Subscription	Instruction	 Identifier	 Crypto/Tokens
60 { H460P_PresenceMessage::e_presenceStatus			,1				,0				,2			,0          ,0 },
61 { H460P_PresenceMessage::e_presenceInstruct			,0				,0				,1			,0			,0 },
62 { H460P_PresenceMessage::e_presenceAuthorize			,0				,1				,0			,0			,0 },
63 { H460P_PresenceMessage::e_presenceNotify			,1				,0				,0			,0			,0 },
64 { H460P_PresenceMessage::e_presenceRequest			,0				,1				,0			,0			,3 },
65 { H460P_PresenceMessage::e_presenceResponse			,0				,1				,0			,0			,2 },
66 { H460P_PresenceMessage::e_presenceAlive			,0				,0				,0			,1			,0 },
67 { H460P_PresenceMessage::e_presenceRemove			,0				,0				,0			,1			,0 },
68 { H460P_PresenceMessage::e_presenceAlert			,1				,0				,0			,0			,0 }
69 };
70 //  0 - not used   1 - mandatory  2 - optional  3 - recommended
71 
72 
73 // Presence message abbreviations
74 const char *PresName[] = {
75 	"Status",
76 	"Instruct",
77 	"Authorize",
78 	"Notify",
79 	"Request",
80 	"Response",
81 	"Alive",
82 	"Remove",
83 	"Alert",
84 	"NotRecognized"		// for new messages
85 };
86 const unsigned MaxPresTag =  H460P_PresenceMessage::e_presenceAlert;
87 
88 
89 ///////////////////////////////////////////////////////////////////
90 
91 struct H323PresenceMessage {
92 	PPER_Stream m_rawPDU;
93 	H460P_PresenceMessage m_recvPDU;
94 	H323PresenceHandler * m_handler;
95 	const H225_EndpointIdentifier * m_id;
96 
GetTagH323PresenceMessage97 	unsigned GetTag() const { return m_recvPDU.GetTag(); }
98 	const char *GetTagName() const;
99 };
100 
101 
GetTagName() const102 const char *H323PresenceMessage::GetTagName() const
103 {
104 	return (GetTag() <= MaxPresTag) ? PresName[GetTag()] : PresName[MaxPresTag+1];
105 }
106 
107 ///////////////////////////////////////////////////////////////////
108 
109 
110 class H323PresenceBase
111 {
112  public:
113 	H323PresenceBase(H323PresenceMessage *m);
~H323PresenceBase()114 	virtual ~H323PresenceBase() {};
115 
116 	bool Process();
117 
118  protected:
119 
120     bool ReadNotification(const H460P_ArrayOf_PresenceNotification & notify);
121 	bool ReadSubscription(const H460P_ArrayOf_PresenceSubscription & subscription);
122 	bool ReadInstruction(const H460P_ArrayOf_PresenceInstruction & instruction);
123 	bool ReadIdentifier(const H460P_ArrayOf_PresenceIdentifier & identifier);
124 
HandleNotification(bool)125 	virtual bool HandleNotification(bool /*opt*/) { return false; }
HandleSubscription(bool)126 	virtual bool HandleSubscription(bool /*opt*/) { return false; }
HandleInstruction(bool)127 	virtual bool HandleInstruction(bool /*opt*/) { return false; }
HandleIdentifier(bool)128 	virtual bool HandleIdentifier(bool /*opt*/) { return false; }
HandleCryptoTokens(bool)129 	virtual bool HandleCryptoTokens(bool /*opt*/) { return false; }
130 
131     unsigned tag;
132     H323PresenceHandler * handler;
133 	const H225_EndpointIdentifier * m_id;
134 };
135 
H323PresenceBase(H323PresenceMessage * m)136 H323PresenceBase::H323PresenceBase(H323PresenceMessage *m)
137 : tag(m->GetTag()), handler(m->m_handler), m_id(m->m_id)
138 {
139 
140 }
141 
Process()142 bool H323PresenceBase::Process()
143 {
144   if (tag > MaxPresTag) {
145 	 PTRACE(2,"PRESENCE\tReceived unrecognised Presence Message!");
146 	 return false;
147   }
148 
149   if (PresenceMessage_attributes[tag].notification > 0)
150 	  HandleNotification((PresenceMessage_attributes[tag].notification >1));
151 
152   if (PresenceMessage_attributes[tag].subscription > 0)
153 	  HandleSubscription((PresenceMessage_attributes[tag].notification >1));
154 
155   if (PresenceMessage_attributes[tag].instruction > 0)
156 	  HandleInstruction((PresenceMessage_attributes[tag].notification >1));
157 
158   if (PresenceMessage_attributes[tag].identifier > 0)
159 	  HandleIdentifier((PresenceMessage_attributes[tag].notification >1));
160 
161   if (PresenceMessage_attributes[tag].cryptoTokens > 0)
162 	  HandleCryptoTokens((PresenceMessage_attributes[tag].notification >1));
163 
164   return true;
165 
166 }
167 
ReadNotification(const H460P_ArrayOf_PresenceNotification & notify)168 bool H323PresenceBase::ReadNotification(const H460P_ArrayOf_PresenceNotification & notify)
169 {
170 	for (PINDEX i = 0; i < notify.GetSize(); i++)
171 		handler->OnNotification((H323PresenceHandler::MsgType)tag, m_id, notify[i]);
172 
173 	return true;
174 }
175 
ReadSubscription(const H460P_ArrayOf_PresenceSubscription & subscription)176 bool H323PresenceBase::ReadSubscription(const H460P_ArrayOf_PresenceSubscription & subscription)
177 {
178 	for (PINDEX i = 0; i < subscription.GetSize(); i++)
179         	handler->OnSubscription((H323PresenceHandler::MsgType)tag, m_id, subscription[i]);
180 
181 	return true;
182 }
183 
ReadInstruction(const H460P_ArrayOf_PresenceInstruction & instruction)184 bool H323PresenceBase::ReadInstruction(const H460P_ArrayOf_PresenceInstruction & instruction)
185 {
186 	handler->OnInstructions((H323PresenceHandler::MsgType)tag, m_id, instruction);
187 	return true;
188 }
189 
ReadIdentifier(const H460P_ArrayOf_PresenceIdentifier & identifier)190 bool H323PresenceBase::ReadIdentifier(const H460P_ArrayOf_PresenceIdentifier & identifier)
191 {
192 	handler->OnIdentifiers((H323PresenceHandler::MsgType)tag, identifier);
193 	return true;
194 }
195 
196 
197 ////////////////////////////////////////////////////////////////////////
198 
199 
200 template<class Msg>
201 class H323PresencePDU : public H323PresenceBase {
202   public:
203 
H323PresencePDU(H323PresenceMessage * m)204 	H323PresencePDU(H323PresenceMessage *m) : H323PresenceBase(m), request(m->m_recvPDU) {}
H323PresencePDU(unsigned tag)205 	H323PresencePDU(unsigned tag) : request(*new Msg) {}
206 
operator Msg&()207 	operator Msg & () { return request; }
operator const Msg&() const208 	operator const Msg & () const { return request; }
209 
210   protected:
211 	Msg & request;
212 };
213 
214 class H323PresenceStatus  : public H323PresencePDU<H460P_PresenceStatus>
215 {
216   public:
H323PresenceStatus(H323PresenceMessage * m)217 	H323PresenceStatus(H323PresenceMessage *m) : H323PresencePDU<H460P_PresenceStatus>(m) {}
218 
219   protected:
220 	virtual bool HandleNotification(bool opt);
221 	virtual bool HandleInstruction(bool opt);
222 };
223 
224 class H323PresenceInstruct  : public H323PresencePDU<H460P_PresenceInstruct>
225 {
226   public:
H323PresenceInstruct(H323PresenceMessage * m)227 	H323PresenceInstruct(H323PresenceMessage *m) : H323PresencePDU<H460P_PresenceInstruct>(m) {}
228 
229   protected:
230 	virtual bool HandleInstruction(bool opt);
231 };
232 
233 class H323PresenceAuthorize  : public H323PresencePDU<H460P_PresenceAuthorize>
234 {
235   public:
H323PresenceAuthorize(H323PresenceMessage * m)236 	H323PresenceAuthorize(H323PresenceMessage *m) : H323PresencePDU<H460P_PresenceAuthorize>(m) {}
237 
238   protected:
239 	virtual bool HandleSubscription(bool opt);
240 };
241 
242 class H323PresenceNotify  : public H323PresencePDU<H460P_PresenceNotify>
243 {
244   public:
H323PresenceNotify(H323PresenceMessage * m)245 	H323PresenceNotify(H323PresenceMessage *m) : H323PresencePDU<H460P_PresenceNotify>(m) {}
246 
247   protected:
248 	virtual bool HandleNotification(bool opt);
249 };
250 
251 class H323PresenceRequest  : public H323PresencePDU<H460P_PresenceRequest>
252 {
253   public:
H323PresenceRequest(H323PresenceMessage * m)254 	H323PresenceRequest(H323PresenceMessage *m) : H323PresencePDU<H460P_PresenceRequest>(m) {}
255 
256   protected:
257 	virtual bool HandleSubscription(bool opt);
258 };
259 
260 class H323PresenceResponse  : public H323PresencePDU<H460P_PresenceResponse>
261 {
262   public:
H323PresenceResponse(H323PresenceMessage * m)263 	H323PresenceResponse(H323PresenceMessage *m) : H323PresencePDU<H460P_PresenceResponse>(m) {}
264 
265   protected:
266 	virtual bool HandleSubscription(bool opt);
267 
268 };
269 
270 class H323PresenceAlive  : public H323PresencePDU<H460P_PresenceAlive>
271 {
272   public:
H323PresenceAlive(H323PresenceMessage * m)273 	H323PresenceAlive(H323PresenceMessage *m) : H323PresencePDU<H460P_PresenceAlive>(m) {}
274 
275   protected:
276 	virtual bool HandleIdentifier(bool opt);
277 };
278 
279 
280 class H323PresenceRemove  : public H323PresencePDU<H460P_PresenceRemove>
281 {
282   public:
H323PresenceRemove(H323PresenceMessage * m)283 	H323PresenceRemove(H323PresenceMessage *m) : H323PresencePDU<H460P_PresenceRemove>(m) {}
284 
285   protected:
286 	virtual bool HandleIdentifier(bool opt);
287 };
288 
289 class H323PresenceAlert  : public H323PresencePDU<H460P_PresenceAlert>
290 {
291   public:
H323PresenceAlert(H323PresenceMessage * m)292 	H323PresenceAlert(H323PresenceMessage *m) : H323PresencePDU<H460P_PresenceAlert>(m) {}
293 
294   protected:
295 	virtual bool HandleNotification(bool opt);
296 
297 };
298 
299 
300 ////////////////////////////////////////////////////////////////////////////
301 
302 
303 
ReceivedPDU(const H225_EndpointIdentifier * id,const PASN_OctetString & pdu)304 bool H323PresenceHandler::ReceivedPDU(const H225_EndpointIdentifier * id, const PASN_OctetString & pdu)
305 {
306     H323PresenceMessage *m = new H323PresenceMessage;
307 	m->m_handler = this;
308 	m->m_id = id;
309 	PPER_Stream raw(pdu);
310 	m->m_rawPDU = raw;
311 	if (!m->m_recvPDU.Decode(raw)) {
312         PTRACE(2,"PRES\tUnable to decode incoming message.");
313 		return false;
314 	}
315 
316 	H323PresenceBase * handler = NULL;
317 	switch (m->GetTag())
318 	{
319 		case H460P_PresenceMessage::e_presenceStatus:
320 			handler = new H323PresenceStatus(m);
321 			break;
322 		case H460P_PresenceMessage::e_presenceInstruct:
323 			handler = new H323PresenceInstruct(m);
324 			break;
325 		case H460P_PresenceMessage::e_presenceAuthorize:
326 			handler = new H323PresenceAuthorize(m);
327 			break;
328 		case H460P_PresenceMessage::e_presenceNotify:
329 			handler = new H323PresenceNotify(m);
330 			break;
331 		case H460P_PresenceMessage::e_presenceRequest:
332 			handler = new H323PresenceRequest(m);
333 			break;
334 		case H460P_PresenceMessage::e_presenceResponse:
335 			handler = new H323PresenceResponse(m);
336 			break;
337 		case H460P_PresenceMessage::e_presenceAlive:
338 			handler = new H323PresenceAlive(m);
339 			break;
340 		case H460P_PresenceMessage::e_presenceRemove:
341 			handler = new H323PresenceRemove(m);
342 			break;
343 		case H460P_PresenceMessage::e_presenceAlert:
344 			handler = new H323PresenceAlert(m);
345 			break;
346 		default:
347 			break;
348 	}
349 
350 	if (handler != NULL && handler->Process())
351 			return true;
352 
353     	PTRACE(2,"PRES\tUnable to handle Message." << m->GetTagName());
354 	return false;
355 }
356 
357 ///////////////////////////////////////////////////////////////////////
358 
359 template<class Msg>
360 class H323PresenceMsg  : public H460P_PresenceMessage
361 {
362  public:
Build(unsigned _tag)363 	Msg & Build(unsigned _tag)
364 	{
365 		SetTag(_tag);
366 		Msg & msg = *this;
367 		return msg;
368 	}
369 };
370 
371 
BuildStatus(H460P_PresenceMessage & msg,const H323PresenceNotifications & notify,const H323PresenceInstructions & inst)372 H460P_PresenceStatus &  H323PresenceHandler::BuildStatus(H460P_PresenceMessage & msg,
373 						const H323PresenceNotifications & notify,
374 						const H323PresenceInstructions & inst)
375 {
376 	H323PresenceMsg<H460P_PresenceStatus> m;
377 	H460P_PresenceStatus & pdu = m.Build(H460P_PresenceMessage::e_presenceStatus);
378 	pdu.m_notification = notify;
379 
380 	if (inst.GetSize() > 0) {
381 		pdu.IncludeOptionalField(H460P_PresenceStatus::e_instruction);
382 		pdu.m_instruction = inst;
383 	}
384 
385 	msg = *(H460P_PresenceMessage *)m.Clone();
386 	return msg;
387 }
388 
BuildInstruct(H460P_PresenceMessage & msg,const H323PresenceInstructions & inst)389 H460P_PresenceInstruct &  H323PresenceHandler::BuildInstruct(H460P_PresenceMessage & msg, const H323PresenceInstructions & inst)
390 {
391 	H323PresenceMsg<H460P_PresenceInstruct> m;
392 	H460P_PresenceInstruct & pdu = m.Build(H460P_PresenceMessage::e_presenceInstruct);
393 	pdu.m_instruction = inst;
394 
395 	msg = *(H460P_PresenceMessage *)m.Clone();
396 	return msg;
397 }
398 
BuildAuthorize(H460P_PresenceMessage & msg,const H323PresenceSubscriptions & subs)399 H460P_PresenceAuthorize &  H323PresenceHandler::BuildAuthorize(H460P_PresenceMessage & msg, const H323PresenceSubscriptions & subs)
400 {
401 	H323PresenceMsg<H460P_PresenceAuthorize> m;
402 	H460P_PresenceAuthorize & pdu = m.Build(H460P_PresenceMessage::e_presenceAuthorize);
403 	pdu.m_subscription = subs;
404 
405 	msg = *(H460P_PresenceMessage *)m.Clone();
406 	return msg;
407 }
408 
BuildNotify(H460P_PresenceMessage & msg,const H323PresenceNotifications & notify)409 H460P_PresenceNotify &  H323PresenceHandler::BuildNotify(H460P_PresenceMessage & msg, const H323PresenceNotifications & notify)
410 {
411 	H323PresenceMsg<H460P_PresenceNotify> m;
412 	H460P_PresenceNotify & pdu = m.Build(H460P_PresenceMessage::e_presenceNotify);
413 	pdu.m_notification = notify;
414 
415 	msg = *(H460P_PresenceMessage *)m.Clone();
416 	return msg;
417 }
418 
BuildRequest(H460P_PresenceMessage & msg,const H323PresenceSubscriptions & subs)419 H460P_PresenceRequest &  H323PresenceHandler::BuildRequest(H460P_PresenceMessage & msg, const H323PresenceSubscriptions & subs)
420 {
421 	H323PresenceMsg<H460P_PresenceRequest> m;
422 	H460P_PresenceRequest & pdu = m.Build(H460P_PresenceMessage::e_presenceRequest);
423 	pdu.m_subscription = subs;
424 
425 	msg = *(H460P_PresenceMessage *)m.Clone();
426 	return msg;
427 }
428 
BuildResponse(H460P_PresenceMessage & msg,const H323PresenceSubscriptions & subs)429 H460P_PresenceResponse &  H323PresenceHandler::BuildResponse(H460P_PresenceMessage & msg, const H323PresenceSubscriptions & subs)
430 {
431 	H323PresenceMsg<H460P_PresenceResponse> m;
432 	H460P_PresenceResponse & pdu = m.Build(H460P_PresenceMessage::e_presenceResponse);
433 	pdu.m_subscription = subs;
434 
435 	msg = *(H460P_PresenceMessage *)m.Clone();
436 	return msg;;
437 }
438 
BuildAlive(H460P_PresenceMessage & msg,const H323PresenceIdentifiers & id)439 H460P_PresenceAlive & H323PresenceHandler::BuildAlive(H460P_PresenceMessage & msg, const H323PresenceIdentifiers & id)
440 {
441 	H323PresenceMsg<H460P_PresenceAlive> m;
442 	H460P_PresenceAlive & pdu = m.Build(H460P_PresenceMessage::e_presenceAlive);
443 	pdu.m_identifier = id;
444 
445 	msg = *(H460P_PresenceMessage *)m.Clone();
446 	return msg;
447 }
448 
BuildRemove(H460P_PresenceMessage & msg,const H323PresenceIdentifiers & id)449 H460P_PresenceRemove & H323PresenceHandler::BuildRemove(H460P_PresenceMessage & msg, const H323PresenceIdentifiers & id)
450 {
451 	H323PresenceMsg<H460P_PresenceRemove> m;
452 	H460P_PresenceRemove & pdu = m.Build(H460P_PresenceMessage::e_presenceRemove);
453 	pdu.m_identifier = id;
454 
455 	msg = *(H460P_PresenceMessage *)m.Clone();
456 	return msg;
457 }
458 
BuildAlert(H460P_PresenceMessage & msg,const H323PresenceNotifications & notify)459 H460P_PresenceAlert &  H323PresenceHandler::BuildAlert(H460P_PresenceMessage & msg, const H323PresenceNotifications & notify)
460 {
461 	H323PresenceMsg<H460P_PresenceAlert> m;
462 	H460P_PresenceAlert & pdu = m.Build(H460P_PresenceMessage::e_presenceAlert);
463 	pdu.m_notification = notify;
464 
465 	msg = *(H460P_PresenceMessage *)m.Clone();
466 	return msg;
467 }
468 
469 ////////////////////////////////////////////////////////////////////////
470 
HandleNotification(bool opt)471 bool H323PresenceStatus::HandleNotification(bool opt)
472 {
473    if (!opt)
474 	   return ReadNotification(request.m_notification);
475 
476    return false;
477 }
478 
HandleNotification(bool opt)479 bool H323PresenceNotify::HandleNotification(bool opt)
480 {
481    if (!opt)
482 	   return ReadNotification(request.m_notification);
483 
484    return false;
485 }
486 
HandleNotification(bool opt)487 bool H323PresenceAlert::HandleNotification(bool opt)
488 {
489    if (!opt)
490 	   return ReadNotification(request.m_notification);
491 
492    return false;
493 }
494 
HandleSubscription(bool opt)495 bool H323PresenceAuthorize::HandleSubscription(bool opt)
496 {
497    if (!opt)
498 	   return ReadSubscription(request.m_subscription);
499 
500    return false;
501 }
502 
HandleSubscription(bool opt)503 bool H323PresenceRequest::HandleSubscription(bool opt)
504 {
505    if (!opt)
506 	   return ReadSubscription(request.m_subscription);
507 
508    return false;
509 }
510 
HandleSubscription(bool opt)511 bool H323PresenceResponse::HandleSubscription(bool opt)
512 {
513    if (!opt)
514 	   return ReadSubscription(request.m_subscription);
515 
516    return false;
517 }
518 
HandleInstruction(bool opt)519 bool H323PresenceStatus::HandleInstruction(bool opt)
520 {
521    if (!opt || request.HasOptionalField(H460P_PresenceStatus::e_instruction))
522 	   return ReadInstruction(request.m_instruction);
523 
524    return false;
525 }
526 
HandleInstruction(bool opt)527 bool H323PresenceInstruct::HandleInstruction(bool opt)
528 {
529    if (!opt)
530 	   return ReadInstruction(request.m_instruction);
531 
532    return false;
533 }
534 
HandleIdentifier(bool opt)535 bool H323PresenceAlive::HandleIdentifier(bool opt)
536 {
537    if (!opt)
538 	   return ReadIdentifier(request.m_identifier);
539 
540    return false;
541 }
542 
HandleIdentifier(bool opt)543 bool H323PresenceRemove::HandleIdentifier(bool opt)
544 {
545    if (!opt)
546 	   return ReadIdentifier(request.m_identifier);
547 
548    return false;
549 }
550 
551 ///////////////////////////////////////////////////////////////////////
552 
H323PresenceInstruction(Instruction instruct,const PString & alias)553 H323PresenceInstruction::H323PresenceInstruction(Instruction instruct, const PString & alias)
554 {
555 	SetTag((unsigned)instruct);
556 	H225_AliasAddress & addr = *this;
557 	H323SetAliasAddress(alias, addr);
558 
559 }
560 
GetInstruction()561 H323PresenceInstruction::Instruction H323PresenceInstruction::GetInstruction()
562 {
563 	return (Instruction)GetTag();
564 }
565 
GetAlias()566 PString H323PresenceInstruction::GetAlias()
567 {
568 	const H225_AliasAddress & addr = *this;
569 	return H323GetAliasAddressString(addr);
570 }
571 
572 ///////////////////////////////////////////////////////////////////////
573 
Add(const H323PresenceInstruction & instruct)574 void H323PresenceInstructions::Add(const H323PresenceInstruction & instruct)
575 {
576     	int size = GetSize();
577 	SetSize(size+1);
578 	array.SetAt(size, instruct.Clone());
579 }
580 
operator [](PINDEX i) const581 H323PresenceInstruction & H323PresenceInstructions::operator[](PINDEX i) const
582 {
583    return (H323PresenceInstruction &)array[i];
584 }
585 
586 static const char *InstructState[] = {
587 	"Subscribe",
588 	"Unsubscribe",
589 	"Block",
590 	"Unblock"
591 };
592 
GetInstructionString(unsigned instruct)593 PString H323PresenceInstruction::GetInstructionString(unsigned instruct)
594 {
595      return InstructState[instruct];
596 }
597 
598 ///////////////////////////////////////////////////////////////////////
599 
Add(const OpalGloballyUniqueID & guid)600 void H323PresenceIdentifiers::Add(const OpalGloballyUniqueID & guid)
601 {
602 	H460P_PresenceIdentifier id;
603 	id.m_guid = guid;
604 	int size = GetSize();
605 	SetSize(size+1);
606 	array.SetAt(size, &id);
607 }
608 
GetIdentifier(PINDEX i)609 OpalGloballyUniqueID H323PresenceIdentifiers::GetIdentifier(PINDEX i)
610 {
611 	H460P_PresenceIdentifier & id = (H460P_PresenceIdentifier &)array[i];
612 	return OpalGloballyUniqueID(id.m_guid);
613 }
614 
615 ////////////////////////////////////////////////////////////////////////
616 
Add(const H323PresenceNotification & notify)617 void H323PresenceNotifications::Add(const H323PresenceNotification & notify)
618 {
619 	int addsize = GetSize();
620 	SetSize(addsize+1);
621 	array.SetAt(addsize, notify.Clone());
622 }
623 
624 
SetPresenceState(H323PresenceNotification::States state,const PString & display)625 void H323PresenceNotification::SetPresenceState(H323PresenceNotification::States state,
626 						const PString & display)
627 {
628 	H460P_Presentity & e = m_presentity;
629 	e.m_state.SetTag((unsigned)state);
630 
631 	if (display.GetLength() > 0) {
632 		e.IncludeOptionalField(H460P_Presentity::e_display);
633 		e.m_display = display;
634 	}
635 }
636 
GetPresenceState(H323PresenceNotification::States & state,PString & display)637 void H323PresenceNotification::GetPresenceState(H323PresenceNotification::States & state,
638 						PString & display)
639 {
640 	H460P_Presentity & e = m_presentity;
641 	state = (H323PresenceNotification::States)e.m_state.GetTag();
642 
643 	if (state != e_generic) {
644 	   if (e.HasOptionalField(H460P_Presentity::e_display))
645 		   display = e.m_display;
646 	} else {
647 	   PASN_BMPString & m = e.m_state;
648        display = m;
649 	}
650 }
651 
SetGenericState(const PString & state)652 void H323PresenceNotification::SetGenericState(const PString & state)
653 {
654 	H460P_Presentity & e = m_presentity;
655 	e.m_state.SetTag(H460P_PresenceState::e_generic);
656 
657 	PASN_BMPString & display = e.m_state;
658 	display = state;
659 }
660 
AddSubscriber(const OpalGloballyUniqueID & guid)661 void H323PresenceNotification::AddSubscriber(const OpalGloballyUniqueID & guid)
662 {
663 	if (!HasOptionalField(H460P_PresenceNotification::e_subscribers))
664 		IncludeOptionalField(H460P_PresenceNotification::e_subscribers);
665 
666 	H460P_PresenceIdentifier id;
667 	id.m_guid = guid;
668 	int size = m_subscribers.GetSize();
669 	m_subscribers.SetSize(size+1);
670 	m_subscribers[size] = id;
671 }
672 
RemoveSubscribers()673 void H323PresenceNotification::RemoveSubscribers()
674 {
675 	if (HasOptionalField(H460P_PresenceNotification::e_subscribers)) {
676 		RemoveOptionalField(H460P_PresenceNotification::e_subscribers);
677 		m_subscribers.RemoveAll();
678 	}
679 }
680 
GetSubscriber(PINDEX i)681 OpalGloballyUniqueID H323PresenceNotification::GetSubscriber(PINDEX i)
682 {
683 	if (HasOptionalField(H460P_PresenceNotification::e_subscribers)) {
684 		H460P_PresenceIdentifier & id = m_subscribers[i];
685 		return OpalGloballyUniqueID(id.m_guid);
686 	}
687 
688 	return OpalGloballyUniqueID();
689 }
690 
AddAlias(const PString & alias)691 void H323PresenceNotification::AddAlias(const PString & alias)
692 {
693 	if (!HasOptionalField(H460P_PresenceNotification::e_aliasAddress))
694 		IncludeOptionalField(H460P_PresenceNotification::e_aliasAddress);
695 
696 	H323SetAliasAddress(alias, m_aliasAddress);
697 }
698 
GetAlias()699 PString H323PresenceNotification::GetAlias()
700 {
701 	if (HasOptionalField(H460P_PresenceNotification::e_aliasAddress))
702 	     return H323GetAliasAddressString(m_aliasAddress);
703 
704  	return PString();
705 }
706 
707 static const char *PresState[] = {
708 	"Hidden",
709 	"Available",
710 	"Online",
711 	"Offline",
712 	"OnCall",
713 	"VoiceMail",
714 	"NotAvailable",
715 	"Generic"
716 };
717 
GetStateString(unsigned state)718 PString H323PresenceNotification::GetStateString(unsigned state)
719 {
720 	return PresState[state];
721 }
722 
723 ///////////////////////////////////////////////////////////////////////
724 
Add(const H323PresenceSubscription & sub)725 void H323PresenceSubscriptions::Add(const H323PresenceSubscription & sub)
726 {
727 	int size = GetSize();
728 	SetSize(size+1);
729 	array.SetAt(size, sub.Clone());
730 }
731 
H323PresenceSubscription()732 H323PresenceSubscription::H323PresenceSubscription()
733 {
734 }
735 
SetSubscriptionDetails(const PString & subscribe,const PStringList & aliases)736 void H323PresenceSubscription::SetSubscriptionDetails(const PString & subscribe, const PStringList & aliases)
737 {
738 	H323SetAliasAddress(subscribe, m_subscribe);
739 
740 	for (PINDEX i=0; i< aliases.GetSize(); i++) {
741 		H225_AliasAddress alias;
742 		H323SetAliasAddress(aliases[i],alias);
743 		int size = m_aliases.GetSize();
744 		m_aliases.SetSize(size+1);
745 		m_aliases[i] = alias;
746 	}
747 }
748 
GetSubscriberDetails(PStringList & aliases)749 void H323PresenceSubscription::GetSubscriberDetails(PStringList & aliases)
750 {
751 	for (PINDEX i=0; i< m_aliases.GetSize(); i++) {
752 		PString a = H323GetAliasAddressString(m_aliases[i]);
753 		aliases.AppendString(a);
754 	}
755 }
756 
GetSubscribed()757 PString H323PresenceSubscription::GetSubscribed()
758 {
759 	return H323GetAliasAddressString(m_subscribe);
760 }
761 
SetGatekeeperRAS(const H323TransportAddress & address)762 void H323PresenceSubscription::SetGatekeeperRAS(const H323TransportAddress & address)
763 {
764 	IncludeOptionalField(H460P_PresenceSubscription::e_rasAddress);
765 	address.SetPDU(m_rasAddress);
766 }
767 
GetGatekeeperRAS()768 H323TransportAddress H323PresenceSubscription::GetGatekeeperRAS()
769 {
770 	if (!HasOptionalField(H460P_PresenceSubscription::e_rasAddress))
771 		return H323TransportAddress();
772 
773 	return H323TransportAddress(m_rasAddress);
774 }
775 
SetApproved(bool success)776 void H323PresenceSubscription::SetApproved(bool success)
777 {
778 	if (HasOptionalField(H460P_PresenceSubscription::e_approved))
779 	        IncludeOptionalField(H460P_PresenceSubscription::e_approved);
780 
781 	m_approved = success;
782 }
783 
IsApproved()784 int H323PresenceSubscription::IsApproved()
785 {
786 	if (HasOptionalField(H460P_PresenceSubscription::e_approved))
787 	  return (int)m_approved;
788 	else
789 	  return -1;
790 }
791 
SetTimeToLive(int t)792 void H323PresenceSubscription::SetTimeToLive(int t)
793 {
794 	IncludeOptionalField(H460P_PresenceSubscription::e_timeToLive);
795 	m_timeToLive = t;
796 }
797 
SetSubscription(const OpalGloballyUniqueID & guid)798 void H323PresenceSubscription::SetSubscription(const OpalGloballyUniqueID & guid)
799 {
800 	IncludeOptionalField(H460P_PresenceSubscription::e_identifier);
801 	m_identifier.m_guid = guid;
802 }
803 
GetSubscription()804 OpalGloballyUniqueID H323PresenceSubscription::GetSubscription()
805 {
806 	if (!HasOptionalField(H460P_PresenceSubscription::e_identifier))
807 		return OpalGloballyUniqueID();
808 
809 	return OpalGloballyUniqueID(m_identifier.m_guid);
810 }
811 
MakeDecision(bool approve)812 void H323PresenceSubscription::MakeDecision(bool approve)
813 {
814 	SetApproved(approve);
815 }
816 
IsDecisionMade()817 bool H323PresenceSubscription::IsDecisionMade()
818 {
819 	return HasOptionalField(H460P_PresenceSubscription::e_approved);
820 }
821 
822 
823 #endif // OPAL_H460
824