1 /*
2 * atobj-sm.cc --
3 *
4 * FIXME: This file needs a description here.
5 *
6 * Copyright (c) 1997-2002 The Regents of the University of California.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * A. Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 * B. Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 * C. Neither the names of the copyright holders nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
22 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #ifndef ATOBJ_SM_CC
35 #define ATOBJ_SM_CC
36
37 #ifndef lint
38 static const char rcsid[] = "$Header: /usr/mash/src/repository/mash/mash-1/atobj/atobj-sm.cc,v 1.16 2003/11/19 19:20:14 aswan Exp $";
39 #endif
40
41 #include "mb/mb.h"
42 #include "mb/mb-nethost.h"
43 #include "atobj/atobj-sm.h"
44
45 extern "C"
46 {
47 #include "rtp/inet.h"
48 #ifndef WIN32
49 #include <unistd.h>
50 #endif
51 #include <sys/types.h>
52 };
53
54 #include "misc/mtrace.h"
55
56 // this is a simple animator session manager
57 static class AtoSMClass : public TclClass {
58 public:
59 AtoSMClass() : TclClass("Atobj_sess_mgr") {
60 }
61
62 TclObject* create(int /*argc*/, const char*const* /*id*/) {
63 return (new AtobjSM());
64 }
65 } AtoSMC;
66
67 AtobjSM::AtobjSM()
68 : SRM_AppMgr(NULL), pLocalRcvr_(NULL), pSession_(NULL)
69 {
70 phtRcvrs_ = new Tcl_HashTable;
71 if (!phtRcvrs_) {
72 SignalError(("Out of Memory!"));
73 abort();
74 }
75 // SrcId must be a of size a multiple of int
76 // otherwise we would use garbage as part of the keys
77 assert((sizeof(SrcId)/sizeof(int))*sizeof(int) == sizeof(SrcId));
78 Tcl_InitHashTable(phtRcvrs_, sizeof(SrcId)/sizeof(int));
79 }
80
81 /*virtual*/
82 AtobjSM::~AtobjSM()
83 {
84 Tcl_HashSearch hsearch;
85 Tcl_HashEntry *pEntry = Tcl_FirstHashEntry(phtRcvrs_, &hsearch);
86 Tcl& tcl=Tcl::instance();
87 while (pEntry) {
88 // these are TclObjects have to do death from
89 // above
90 AtobjRcvr *pRcvr = (AtobjRcvr *)Tcl_GetHashValue(pEntry);
91 pEntry = Tcl_NextHashEntry(&hsearch);
92 tcl.evalf("delete %s", pRcvr->name());
93 }
94 Tcl_DeleteHashTable(phtRcvrs_);
95 delete phtRcvrs_;
96 }
97
98 // virtual SRM_AppMgr functions
99 SRM_PacketHandler *
100 AtobjSM::new_source(const srm_src &sid, int islocal)
101 {
102 if (islocal) return NULL;
103 return (SRM_PacketHandler*) define_rcvr(sid);
104 }
105
106 // checks if there is a receiver with such an id
107 AtobjRcvr* AtobjSM::get_rcvr(const SrcId& srcId)
108 {
109 Tcl_HashEntry *pEntry = Tcl_FindHashEntry(phtRcvrs_, (char*)&srcId);
110 if (!pEntry) return NULL;
111 else return (AtobjRcvr*)Tcl_GetHashValue(pEntry);
112 }
113
114 AtobjRcvr* AtobjSM::define_rcvr(const SrcId& srcId)
115 {
116 int created;
117 Tcl& tcl=Tcl::instance();
118
119 Tcl_HashEntry *pNewEntry =
120 Tcl_CreateHashEntry(phtRcvrs_, (char*)&srcId, &created);
121 if (created) {
122 Trace(VERBOSE, ("creating new receiver: %d@%s",
123 srcId.ss_uid, intoa(srcId.ss_addr)));
124 tcl.evalf("%s new_rcvr %lx %lx", name(), srcId.ss_uid,
125 srcId.ss_addr);
126 AtobjRcvr* pRcvr =
127 (AtobjRcvr*)TclObject::lookup(tcl.result());
128 Trace(VERBOSE, ("result: %x %d@%s",
129 pRcvr, srcId.ss_uid, intoa(srcId.ss_addr)));
130 assert(pRcvr && "new receiver failed!");
131 Tcl_SetHashValue(pNewEntry, (ClientData) pRcvr);
132 return pRcvr;
133 } else {
134 return (AtobjRcvr*)Tcl_GetHashValue(pNewEntry);
135 }
136 }
137
138 int AtobjSM::command(int /*argc*/, const char*const* argv)
139 {
140 if (!strcmp(argv[1], "attach_session")) {
141 SRM_Session* pSession =
142 (SRM_Session*)TclObject::lookup(argv[2]);
143 if (!pSession) {
144 Tcl::instance().result("Couldn't find session");
145 return TCL_ERROR;
146 }
147 setSession(pSession);
148 } else if (!strcmp(argv[1], "set_local_src")) {
149 // this is not a requirement, just something
150 // that I might assume
151 assert(!pLocalRcvr_ && "shouldn't set local twice");
152 pLocalRcvr_ = (AtobjRcvr*) TclObject::lookup(argv[2]);
153 const SrcId& sid = pLocalRcvr_->srcId();
154 fprintf(stderr, "localsrc is %s (%d@%s)\n",
155 pLocalRcvr_->name(),
156 sid.ss_uid, intoa(sid.ss_addr));
157 if (!get_rcvr(sid)) {
158 int created;
159 Tcl_HashEntry *pNewEntry =
160 Tcl_CreateHashEntry(phtRcvrs_,
161 (char*)&sid, &created);
162 Tcl_SetHashValue(pNewEntry, (ClientData) pLocalRcvr_);
163 }
164 if (!pLocalRcvr_) {
165 Tcl::instance().result("Couldn't find local src");
166 return TCL_ERROR;
167 }
168 } else if (!strcmp(argv[1],"abort")) {
169 assert(FALSE && "progam aborted");
170 Tcl::instance().eval("exit");
171 }
172 return TCL_OK;
173 }
174
175 //
176 // handles a repair request from the net
177 //
178 /*virtual*/
179 void AtobjSM::handle_request(const SrcId& sidRqtSrc, Byte *pb, int /* len */)
180 {
181 if (pLocalRcvr_ && pLocalRcvr_->srcId() == sidRqtSrc) {
182 return; // ignore own request
183 }
184 AtoPkt_request* pPkt = (AtoPkt_request*) pb;
185 SrcId srcId;
186 net2host(pPkt->pr_srcId, srcId);
187 Trace(VERBOSE,("r rqt (%d B) fr %x@%s",
188 sidRqtSrc.ss_uid, intoa(sidRqtSrc.ss_addr)));
189
190 AtobjRcvr *pRcvr = get_rcvr(srcId); // drop the request from ourselves
191 if (pRcvr) pRcvr->handleRequest(pPkt);
192 if (!pRcvr) Trace(VERBOSE,
193 ("request for data of unknown source %d@%s\n",
194 srcId.ss_uid, intoa(srcId.ss_addr)));
195 }
196
197 //
198 // handle a repair reply
199 //
200 /*virtual*/
201 #ifdef MB_DEBUG
202 void AtobjSM::handle_reply(const SrcId& sidRpySrc, Byte *pb, int len)
203 #else
204 void AtobjSM::handle_reply(const SrcId& sidRpySrc, Byte *pb, int /* len */)
205 #endif
206 {
207 if (pLocalRcvr_ && pLocalRcvr_->srcId() == sidRpySrc) {
208 return; // ignore own request
209 }
210 AtoPkt_reply* pPkt = (AtoPkt_reply*) pb;
211 SrcId srcId;
212 net2host(pPkt->pr_srcId, srcId);
213 Trace(VERYVERBOSE,("recv reply: %d bytes from %d@%s\n",len, srcId.ss_uid,
214 intoa(srcId.ss_addr)));
215
216 AtobjRcvr *pRcvr = get_rcvr(srcId);
217 if (pRcvr) pRcvr->handleReply(pPkt);
218 if (!pRcvr) Trace(VERBOSE,("reply from unknown receiver: %d@%s\n",
219 srcId.ss_uid, intoa(srcId.ss_addr)));
220
221 }
222
223 #ifdef MB_DEBUG
224 void AtobjSM::handle_SA(const SrcId& sid, Byte * pb, int len)
225 #else
226 void AtobjSM::handle_SA(const SrcId& sid, Byte * pb, int /* len */)
227 #endif
228 {
229 if (pLocalRcvr_ && pLocalRcvr_->srcId()==sid) {
230 return; // ignore local sa's
231 }
232 AtoPkt_SA* pPkt = (AtoPkt_SA*) pb;
233 SrcId srcId;
234 net2host(pPkt->sa_srcId, srcId);
235 if (srcId.ss_uid == 0 && srcId.ss_addr==0) {
236 return; // empty srcId
237 }
238 Trace(VERBOSE,("recv'd SA of %d bytes from %d@%s",
239 len, srcId.ss_uid, intoa(srcId.ss_addr)));
240 AtobjRcvr *pRcvr = define_rcvr(srcId);
241 assert(pRcvr);
242 pRcvr->handleSA(pPkt);
243 if (!pRcvr) Trace(VERBOSE,("SA from unknown receiver: %d@%s\n",
244 srcId.ss_uid, intoa(srcId.ss_addr)));
245 }
246
247 // if a receiver has requested a SA, service them first, else
248 // ask the local receiver to send out the SA
249 int AtobjSM::periodic_update(Byte * pb)
250 {
251 if (!pLocalRcvr_) return 0;
252
253 // right now just use local receiver only
254 // REVIEW: take care of initial start up problem
255 int len = pLocalRcvr_->fillSA(pb);
256 Trace(VERBOSE,("sending app sa: of %d bytes", len));
257 return len;
258 }
259
260 #endif /* #ifdef ATOBJ_MGR_CC */
261
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.