Beaming Scene Service  2.0
RakNet wrapper for managing data communications between multiple Beaming clients
xmppClient/echoClient.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008-2011 The QXmpp developers
00003  *
00004  * Author:
00005  *      Manjeet Dahiya
00006  *
00007  * Source:
00008  *      http://code.google.com/p/qxmpp
00009  *
00010  * This file is a part of QXmpp library.
00011  *
00012  * This library is free software; you can redistribute it and/or
00013  * modify it under the terms of the GNU Lesser General Public
00014  * License as published by the Free Software Foundation; either
00015  * version 2.1 of the License, or (at your option) any later version.
00016  *
00017  * This library is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020  * Lesser General Public License for more details.
00021  *
00022  */
00023 
00024 
00025 #include "echoClient.h"
00026 #include "QXmppMessage.h"
00027 #include "QXmppPresence.h"
00028 #include <iostream>
00029 #include "client.h"
00030 #include "Kbhit.h"
00031 #include "Getche.h"
00032 
00033 echoClient::echoClient(QObject *parent)
00034     : QXmppClient(parent)
00035 {
00036     bool check = connect(this, SIGNAL(messageReceived(const QXmppMessage&)),
00037         SLOT(messageReceived(const QXmppMessage&)));
00038     Q_ASSERT(check);
00039     Q_UNUSED(check);
00040         check = connect(this, SIGNAL(presenceReceived(const QXmppPresence&)),
00041         SLOT(presenceReceived(const QXmppPresence&)));
00042     Q_ASSERT(check);
00043     Q_UNUSED(check);
00044     check = connect(this, SIGNAL(connected()),
00045         SLOT(connected()));
00046     Q_ASSERT(check);
00047     Q_UNUSED(check);
00048     check = connect(this, SIGNAL(disconnected()),
00049         SLOT(disconnected()));
00050     Q_ASSERT(check);
00051     Q_UNUSED(check);
00052 }
00053 
00054 echoClient::~echoClient()
00055 {
00056 
00057 }
00058 
00059 void echoClient::messageReceived(const QXmppMessage& message)
00060 {
00061     QString from = message.from();
00062     QString msg = message.body();
00063         QString reply;
00064 
00065         //std::cout << "from " << from.toStdString() << "; msg " << msg.toStdString() << std::endl;
00066         ReadText(msg,reply);
00067         if (!reply.isEmpty())
00068                 sendPacket(QXmppMessage("", from, reply)); //from may need to be hard-coded as "bpserverucl@srv-beaming"
00069 }
00070 
00071 void echoClient::presenceReceived(const QXmppPresence& presence)
00072 {
00073     QString from = presence.from();
00074     sendPresence(from);
00075         if (presence.type() == QXmppPresence::Available)
00076         {
00077                 sendPacket(QXmppMessage("cmmanager", from, "CM_CLIENT_CONNECTED")); 
00078         }
00079 }
00080 
00081 void echoClient::sendPresence(QString msg_from)
00082 {
00083     QString from = msg_from;
00084     QXmppPresence available;
00085     available.setTo(from);
00086         available.setType(QXmppPresence::Available);
00087     sendPacket(available);
00088 }
00089 
00090 void echoClient::connected()
00091 {
00092         connected_to_bss = startclient(/*"128.16.7.66"*/"127.0.0.1", 12050, "IBM CLIENT", "AVATAR", "m016.cfg", false);
00093     if (connected_to_bss)       {
00094                 sendPacket(QXmppMessage("cmmanager", "bpserverucl@srv-beaming", "CM_CLIENT_CONNECTED"));
00095                 sendPresence("bpserverucl@srv-beaming");
00096         } else {
00097                 sendPacket(QXmppMessage("cmmanager", "bpserverucl@srv-beaming", "CM_CLIENT_NOT_CONNECTED"));
00098         }
00099         timer = new QTimer(this);
00100         bool check = connect(timer, SIGNAL(timeout()), this, SLOT(PositionUpdateTimer()));
00101         Q_ASSERT(check);
00102         Q_UNUSED(check);
00103         timer->start(1000); //one second (1000 millisecond) timer
00104 }
00105 
00106 void echoClient::disconnected()
00107 {
00108     removeAllNodes();
00109     stop();
00110 }
00111 
00112 void echoClient::ReadText(QString in_msg, QString& out_msg)
00113 {
00114         char id_cstr[32];
00115         QStringList inputList = in_msg.split(",");              //split on ;
00116         if (!connected_to_bss) 
00117         {
00118                 sendPacket(QXmppMessage("cmmanager", "bpserverucl@srv-beaming", "CM_CLIENT_NOT_CONNECTED"));
00119                 return;
00120         } 
00124     if (in_msg.startsWith("BP_LOGIN_USER"))
00125     {
00126                 QString bpid = "";
00127                 bpid = inputList[1].split("=")[1]; //split on = and save the id and send back as cmid
00128                 sprintf(id_cstr,"%s",bpid.toStdString().c_str()); 
00129         if (addRocketBoxAvatar(id_cstr,"m001.cfg"))
00130                 {
00131                          //inform BP of successful login as AVATAR has been added 
00132                          //CM_LOGIN_USER_RES,bpid={bpid},cmid={cmid}
00133                         std::cout << "AVATAR " << id_cstr << " added" << std::endl;
00134                         out_msg = "CM_LOGIN_USER_RES,bpid=" + bpid + ",cmid=" + bpid;
00135                 } else
00136                 {
00137                         //if xmpp client was unable to connect to Beaming Scene Service, inform BP
00138                         //CM_LOGIN_USER_FAILURE,id={bpid},fname={first name},lname={last name},error={error}
00139             out_msg = "CM_LOGIN_USER_FAILURE,id=" + bpid + ",fname=" + inputList[2].split("=")[1] + ",lname=" + inputList[3].split("=")[1] + ",error=USER_NOT_ADDED";
00140                 }
00141                 return;
00142     }
00143     else if (in_msg.startsWith("BP_LOGOFF_USER"))
00144     /*
00145      * BP_LOGOFF_USER,id={cmid}
00146      */
00147     {
00148                 sprintf(id_cstr,"%s",inputList[1].split("=")[1].toStdString().c_str());
00149                 deleteRocketBoxAvatar(id_cstr);
00150         return;
00151     }
00152     else if (in_msg.startsWith("BP_USER_POSITION"))
00153     /*
00154      * BP_USER_POSITION,id={cmid},x={x},y={y},z={z},ax={ax},ay={ay},az={az},aw={aw}
00155      */
00156     // Pelvis is the only joint currently used as the user's position. 
00157     {
00158                 sprintf(id_cstr,"%s",inputList[1].split("=")[1].toStdString().c_str());
00159                 //printf("%s\n",id_cstr);
00160                 //updates root position which is 0 in the Rocketbox Avatar format
00161         updateRocketBoxAvatar(id_cstr,"0",inputList[2].split("=")[1].toFloat(),
00162                         inputList[3].split("=")[1].toFloat(),inputList[4].split("=")[1].toFloat(),
00163                         inputList[5].split("=")[1].toFloat(),inputList[6].split("=")[1].toFloat(),
00164                         inputList[7].split("=")[1].toFloat(),inputList[8].split("=")[1].toFloat());
00165                 printf("%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f\n",inputList[2].split("=")[1].toFloat(),
00166                         inputList[3].split("=")[1].toFloat(),inputList[4].split("=")[1].toFloat(),
00167                         inputList[5].split("=")[1].toFloat(),inputList[6].split("=")[1].toFloat(),
00168                         inputList[7].split("=")[1].toFloat(),inputList[8].split("=")[1].toFloat());
00169                 return;
00170     }
00171 
00172     /*
00173      * BP_RESET,id={cmid}
00174      */
00175     else if (in_msg.startsWith("BP_RESET"))
00176     {
00177                 printf("Removing all created nodes.\n");
00178                 removeAllNodes();
00179                 return;
00180     }
00181 
00182     //out_msg = "CM_ERROR,error=unknown message";
00183 }
00184 
00185 /*
00186  * This function should be executed by timer
00187  */
00188 void echoClient::PositionUpdateTimer()
00189 {
00190         //Reading AVATAR data
00191         //get information on all connected clients. 
00192         char connectedclients[1024];
00193         char *guid, *node, *tmpid;
00194         char allnodes[2048], node_info[256];
00195         int loop = 0;
00196         float data[7] = {0.f};
00197         char iddata[128];
00198         char ch;
00199         char fname[128], lname[128];
00200         //regularly check incoming connections, pings, etc
00201         check();
00202         if (kbhit())
00203         {
00204                 ch=getch();
00205                 if (ch=='q' || ch=='Q' || ch==27)
00206                 {
00207                         sendPacket(QXmppMessage("cmmanager", "bpserverucl@srv-beaming", "CM_CLIENT_NOT_CONNECTED"));
00208                         printf("Quitting.\n");
00209                         removeAllNodes();
00210                         stop();
00211                         exit(1);
00212                 }
00213         }
00214         //printf("number of connected clients %i\t",getPeersID(connectedclients));
00215         getPeersID(connectedclients);
00216         //printf("connected clients (getPeersID): %s\n",connectedclients);
00217         for (guid = strtok (connectedclients, ";"); guid != NULL;
00218            guid = strtok (guid + strlen (guid) + 1, ";"))
00219         {
00220                 strncpy (iddata, guid, sizeof (iddata));
00221                 printf ("GUID: %s\n", iddata);
00222                 //for each connected guid in the database, get the nodes information.
00223                 //printf("Number of nodes %i\n",getNodesInfo(iddata,allnodes));
00224                 getNodesInfo(iddata,allnodes);
00225                 for (node = strtok (allnodes, ";"); node != NULL;
00226                    node = strtok (node + strlen (node) + 1, ";"))
00227                 {
00228                         strncpy (node_info, node, sizeof (node_info));
00229                         //printf (" Node: %s\n", node_info);
00230                         for (tmpid = strtok (node_info, ","); tmpid != NULL;
00231                            tmpid = strtok (tmpid + strlen (tmpid) + 1, ","))
00232                         {
00233                                 static char avid[128];//, fname[128];
00234                                 switch (loop) 
00235                                 {
00236                                 case 0:// first token is the avatar id
00237                                         //printf ("  Avatar id: %s\n", tmpid);
00238                                         strncpy(avid,tmpid,sizeof(avid));
00239                                         break;
00240                                 case 1:// second token is the avatar name
00241                                         //printf ("  Avatar name: %s\n", tmpid);
00242                                         //strncpy(fname,tmpid,sizeof(fname));
00243                                         break;
00244                                 case 2: //third token is the TYPE
00245                                         if (!strcmp(tmpid,"AVATAR")) //only process if type is AVATAR
00246                                         {
00247                                                 //get AVATAR root node "0" 
00248                                                 if (getAvatarSpecificData(iddata,avid,"0",data))
00249                                                 {
00250                                                         //printf("   Specific data for 0: %.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f\n",data[0],data[1],data[2],data[3],data[4],data[5],data[6]);
00252                                                         getAvatarName(iddata,avid,fname,lname);
00253                                                         printf("   Avatar Name: %s %s\n",fname,lname);
00254                                                         char msg_cstr[128];
00255                                                         //sprintf(msg_cstr,"CM_USER_POSITION,id=%s,fname=%s,lname=lastname,x=%.3f,y=%.3f,z=%.3f,ax=%.3f,ay=%.3f,az=%.3f,aw=%.3f",iddata,avid,data[0],data[1],data[2],data[3],data[4],data[5],data[6]);
00256                                                         sprintf(msg_cstr,"CM_USER_POSITION,ConnId=%s,id=%s,fname=%s,lname=%s,x=%.3f,y=%.3f,z=%.3f,ax=%.3f,ay=%.3f,az=%.3f,aw=%.3f",iddata,avid,fname,lname,data[0],data[1],data[2],data[3],data[4],data[5],data[6]);
00257                                                         std::string msg_stdstr = msg_cstr;
00258                                                         sendPacket(QXmppMessage("", "bpserverucl@srv-beaming", QString::fromStdString(msg_stdstr))); 
00259                                                 }
00260                                         } //else 
00261                                                 //printf("   %s - Not AVATAR\t",tmpid);
00262                                         break;
00263                                 }
00264                                 loop++;
00265                         }
00266                         loop=0;
00267                 }
00268         }
00269 }
 All Classes Files Functions Variables Enumerations Enumerator Defines