Index: trunk/msgsrv.cpp
===================================================================
--- trunk/msgsrv.cpp	(revision 13)
+++ trunk/msgsrv.cpp	(revision 14)
@@ -16,5 +16,5 @@
 // --------------------------------------------------------------
 
-typedef struct
+typedef struct LoginSession
 {
 	cf::network::tcp * sock;
@@ -22,7 +22,7 @@
 } LoginSession;
 std::map<std::string, LoginSession> gOnlineUsers;
-
-
-//================================================================
+std::map<std::string, std::vector<std::string> > gSessionMap;
+
+// --------------------------------------------------------------
 
 int cb_getFriendList(void * userArg, int argc, char ** argv, char ** colName)
@@ -75,4 +75,5 @@
 		: db(NULL)
 	{
+		Init();
 	}
 	
@@ -139,11 +140,11 @@
 		throw(cf::exception)
 	{
-		int result;
-		char * errMsg;
+		int result = 0;
+		char * errMsg = NULL;
 
 		result = sqlite3_exec(db, query.c_str(), cb, userArg, &errMsg);
 
 		if (result != SQLITE_OK)
-			THROW_EXCEPTION (errMsg);
+			THROW_EXCEPTION("[DBERROR][" << result << "] " << errMsg);
 	}
 
@@ -163,6 +164,4 @@
 		{
 			FORWARD_EXCEPTION(e);
-
-			return false;
 		}
 	}
@@ -175,5 +174,5 @@
 			bool isExist = false;
 			std::string existQuery = "select * from T_ACCOUNT where id = '" + id + "'";
-			std::string insertQuery = "insert into T_ACCOUNT values('" + id + "', '" + pw + "', '" + sms + "', '" + ip + "')";
+			std::string insertQuery = "insert into T_ACCOUNT(id, pw) values('" + id + "', '" + pw + "')";
 
 			this->exec(existQuery, cb_join, &isExist);
@@ -282,4 +281,21 @@
 {
 	gOnlineUsers.erase(id);
+	LOG(STR(id << " was logged out"));
+}
+
+static unsigned int generateSeed()
+{
+	unsigned int ret = 0;
+	int t = (int)time(NULL);
+
+	cf::bin b;
+	b.resize(sizeof(int));
+
+	b.set((cf::uint8_t*)&t, sizeof(int));
+	cf::bin s = crypto().sha256(b);
+
+	memcpy(&ret, s.buffer(), sizeof(unsigned int));
+
+	return ret;
 }
 
@@ -287,5 +303,5 @@
 {
 	char random[8] = {0x00,};
-	sprintf(random, "%06d", rand() % 1000000);
+	sprintf(random, "%06d", generateSeed() % 1000000);
 
 	return random;
@@ -294,5 +310,5 @@
 static std::string httpSMS(const Protocol::Message & parser)
 {
-	std::string phone = parser.get<std::string>("phone");
+	std::string phone = parser.get<std::string>(ProtocolType::PHONE);
 
 #define CRLF    "\r\n"
@@ -306,5 +322,4 @@
 		CRLF;
 
-	Protocol::Response response;
 	cf::network::tcp smsSock;
 	cf::network::host smsServer(url, 80);
@@ -312,4 +327,5 @@
 	smsSock.connect(smsServer);
 	smsSock.send(http);
+	smsSock.receive();
 	smsSock.close();
 
@@ -329,5 +345,5 @@
 }
 
-static bool login(const Protocol::Message & parser)
+static bool login(const Protocol::Message & parser, cf::network::tcp & sock, cf::bin & key)
 	throw (cf::exception)
 {
@@ -335,16 +351,33 @@
 	std::string pw = parser.get<std::string>(ProtocolType::PW);
 
-	return dbmgr.login(id, pw);
-}
-
-static bool chat(const Protocol::Message & parser,
-				 const std::string & message)
+	bool result = dbmgr.login(id, pw);
+	if (result)
+	{
+		LoginSession loginSess;
+		loginSess.sock = &sock;
+		loginSess.key = key;
+		gOnlineUsers[id] = loginSess;
+	}
+
+	return result;
+}
+
+static bool chat(const Protocol::Message & message)
 {
 	bool result = false;
-	std::string to = parser.get<std::string>(ProtocolType::TO);
-
-	if (isOnline(to))
-	{
-		gOnlineUsers[to].sock->send(message);
+	Protocol::Message parser = message;
+	std::string sessid = parser.get<std::string>(ProtocolType::SESSION_ID);
+	std::vector<std::string> idList = gSessionMap[sessid];
+	std::string sender = parser.get<std::string>(ProtocolType::ID);
+	parser.mObject[ProtocolType::TYPE] = ProtocolType::LISTEN;
+	std::string serialized = parser.serialize();
+
+	for (size_t iter = 0; iter < idList.size(); iter++)
+	{
+		std::string id = idList[iter];
+
+		if (sender != id && isOnline(id))
+			gOnlineUsers[id].sock->send(serialized);
+
 		result = true;
 	}
@@ -362,24 +395,28 @@
 }
 
-static bool opensession(const Protocol::Message & parser)
-{
+static bool openSession(const Protocol::Message & message)
+{
+	Protocol::Message parser = message;
 	bool result = false;
 	std::string sessid;
 	std::vector<std::string> idList = parser.getList<std::string>(ProtocolType::ID_LIST);
-	std::string concat = idList[0];
-
-	for (size_t iter = 1; iter < concat.size(); iter++)
-		concat += idList[iter];	
+	std::string concat = joinStrings(idList);
 
 	sessid = createSessionID(concat);
 
+	parser.mObject[ProtocolType::SESSION_ID] = sessid;
+	std::string serialized = parser.serialize();
+
 	for (size_t iter = 0; iter < idList.size(); iter++)
 	{
-		if (isOnline(idList[iter]))
-			gOnlineUsers[idList[iter]].sock->send(sessid);
+		std::string id = idList[iter];
+		if (isOnline(id))
+			gOnlineUsers[id].sock->send(serialized);
 
 		result = true;
 	}
 
+	gSessionMap[sessid] = idList;
+
 	return result;
 }
@@ -396,31 +433,46 @@
 static std::string workerInitiator(cf::network::tcp & sock)
 {
+	Protocol::Message parser;
+
 	try
 	{
 		std::string sms;
+		std::string id;
+		bool loggedIn = false;
 
 		while (true)
 		{
-			Protocol::Message parser;
 			parser.parse(sock.receive().toString());
 
-			if (parser.type() == "sms")
+			if (parser.type() == ProtocolType::SMS)
 			{
 				sms = httpSMS(parser);
 			}
-			else if (parser.type() == "join")
+			else if (parser.type() == ProtocolType::JOIN)
 			{
-				if (join(parser, sms, sock.peer().address()))
+				if (!join(parser, sms, sock.peer().address()))
 					THROW_EXCEPTION("user(" << parser.get<std::string>(ProtocolType::ID) << ") cannot join");
 			}
-			else if (parser.type() == "login")
+			else if (parser.type() == ProtocolType::LOGIN)
 			{
-				if (login(parser))
-					parser.get<std::string>(ProtocolType::ID);
-			}			
+				std::string ip = sock.peer().address();
+				cf::bin seed = sms + DELIMITER + ip;
+				cf::bin key = crypto().sha256(seed);
+
+				if (login(parser, sock, key))
+					id = parser.get<std::string>(ProtocolType::ID);
+
+				loggedIn = true;
+			}
+
+			// success
+			sock.send(Protocol::Response().result(parser.type(), true));
+			if (loggedIn)
+				return id;
 		}
 	}
 	catch (cf::exception & e)
 	{
+		sock.send(Protocol::Response().result(parser.type(), false));
 		FORWARD_EXCEPTION(e);
 	}
@@ -436,5 +488,5 @@
 	try
 	{
-		workerInitiator(*sock);
+		id = workerInitiator(*sock);
 
 		Protocol::Response response;
@@ -449,17 +501,18 @@
 			LOG(message);
 
-			if (parser.type() == "chat")
-				result = chat(parser, message);
-			else if (parser.type() == "opensession")
-				result = opensession(parser);
-//			else if (parser.type() == "getFriendList")
-//				result = 
-
-			sock->send(response.result(parser.type(), result));
+			if (parser.type() == ProtocolType::TELL)
+			{
+				result = chat(parser);
+				sock->send(response.result(parser.type(), result));
+			}
+			else if (parser.type() == ProtocolType::OPEN_SESSION)
+			{
+				result = openSession(parser);
+			}
 		}
 	}
 	catch (cf::exception & e)
 	{
-		LOG(e.what());
+		LOG(e.stackTrace());
 	}
 
@@ -472,6 +525,4 @@
 {
 	cf::network::tcp sock;
-
-	srand((unsigned int)time(NULL));
 
 	try
