1 #ifndef __XBMC_CLIENT_H__ 2 #define __XBMC_CLIENT_H__ 3 4 /* 5 * Copyright (C) 2008-2013 Team XBMC 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program; if not, write to the Free Software Foundation, Inc., 19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 */ 21 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 #include <sys/types.h> 26 #ifdef _WIN32 27 #include <winsock.h> 28 #else 29 #include <sys/socket.h> 30 #include <netinet/in.h> 31 #include <netdb.h> 32 #include <arpa/inet.h> 33 #endif 34 #include <vector> 35 #include <iosfwd> 36 #include <fstream> 37 #include <time.h> 38 39 #define STD_PORT 9777 40 41 #define MS_ABSOLUTE 0x01 42 //#define MS_RELATIVE 0x02 43 44 #define BTN_USE_NAME 0x01 45 #define BTN_DOWN 0x02 46 #define BTN_UP 0x04 47 #define BTN_USE_AMOUNT 0x08 48 #define BTN_QUEUE 0x10 49 #define BTN_NO_REPEAT 0x20 50 #define BTN_VKEY 0x40 51 #define BTN_AXIS 0x80 52 53 #define PT_HELO 0x01 54 #define PT_BYE 0x02 55 #define PT_BUTTON 0x03 56 #define PT_MOUSE 0x04 57 #define PT_PING 0x05 58 #define PT_BROADCAST 0x06 59 #define PT_NOTIFICATION 0x07 60 #define PT_BLOB 0x08 61 #define PT_LOG 0x09 62 #define PT_ACTION 0x0A 63 #define PT_DEBUG 0xFF 64 65 #define ICON_NONE 0x00 66 #define ICON_JPEG 0x01 67 #define ICON_PNG 0x02 68 #define ICON_GIF 0x03 69 70 #define MAX_PACKET_SIZE 1024 71 #define HEADER_SIZE 32 72 #define MAX_PAYLOAD_SIZE (MAX_PACKET_SIZE - HEADER_SIZE) 73 74 #define MAJOR_VERSION 2 75 #define MINOR_VERSION 0 76 77 #define LOGDEBUG 0 78 #define LOGINFO 1 79 #define LOGNOTICE 2 80 #define LOGWARNING 3 81 #define LOGERROR 4 82 #define LOGSEVERE 5 83 #define LOGFATAL 6 84 #define LOGNONE 7 85 86 #define ACTION_EXECBUILTIN 0x01 87 #define ACTION_BUTTON 0x02 88 89 class CAddress 90 { 91 private: 92 struct sockaddr_in m_Addr; 93 public: 94 CAddress(int Port = STD_PORT) 95 { 96 m_Addr.sin_family = AF_INET; 97 m_Addr.sin_port = htons(Port); 98 m_Addr.sin_addr.s_addr = INADDR_ANY; 99 memset(m_Addr.sin_zero, '\0', sizeof m_Addr.sin_zero); 100 } 101 102 CAddress(const char *Address, int Port = STD_PORT) 103 { 104 m_Addr.sin_port = htons(Port); 105 106 struct hostent *h; 107 if (Address == NULL || (h=gethostbyname(Address)) == NULL) 108 { 109 if (Address != NULL) 110 printf("Error: Get host by name\n"); 111 112 m_Addr.sin_addr.s_addr = INADDR_ANY; 113 m_Addr.sin_family = AF_INET; 114 } 115 else 116 { 117 m_Addr.sin_family = h->h_addrtype; 118 m_Addr.sin_addr = *((struct in_addr *)h->h_addr); 119 } 120 memset(m_Addr.sin_zero, '\0', sizeof m_Addr.sin_zero); 121 } 122 SetPort(int port)123 void SetPort(int port) 124 { 125 m_Addr.sin_port = htons(port); 126 } 127 GetAddress()128 const sockaddr *GetAddress() 129 { 130 return ((struct sockaddr *)&m_Addr); 131 } 132 Bind(int Sockfd)133 bool Bind(int Sockfd) 134 { 135 return (bind(Sockfd, (struct sockaddr *)&m_Addr, sizeof m_Addr) == 0); 136 } 137 }; 138 139 class XBMCClientUtils 140 { 141 public: XBMCClientUtils()142 XBMCClientUtils() {} ~XBMCClientUtils()143 ~XBMCClientUtils() {} GetUniqueIdentifier()144 static unsigned int GetUniqueIdentifier() 145 { 146 static time_t id = time(NULL); 147 return (unsigned int)id; 148 } 149 Clean()150 static void Clean() 151 { 152 #ifdef _WIN32 153 WSACleanup(); 154 #endif 155 } 156 Initialize()157 static bool Initialize() 158 { 159 #ifdef _WIN32 160 WSADATA wsaData; 161 if (WSAStartup(MAKEWORD(1, 1), &wsaData)) 162 return false; 163 #endif 164 return true; 165 } 166 }; 167 168 class CPacket 169 { 170 /* Base class that implements a single event packet. 171 172 - Generic packet structure (maximum 1024 bytes per packet) 173 - Header is 32 bytes long, so 992 bytes available for payload 174 - large payloads can be split into multiple packets using H4 and H5 175 H5 should contain total no. of packets in such a case 176 - H6 contains length of P1, which is limited to 992 bytes 177 - if H5 is 0 or 1, then H4 will be ignored (single packet msg) 178 - H7 must be set to zeros for now 179 180 ----------------------------- 181 | -H1 Signature ("XBMC") | - 4 x CHAR 4B 182 | -H2 Version (eg. 2.0) | - 2 x UNSIGNED CHAR 2B 183 | -H3 PacketType | - 1 x UNSIGNED SHORT 2B 184 | -H4 Sequence number | - 1 x UNSIGNED LONG 4B 185 | -H5 No. of packets in msg | - 1 x UNSIGNED LONG 4B 186 | -H6 Payload size | - 1 x UNSIGNED SHORT 2B 187 | -H7 Client's unique token | - 1 x UNSIGNED LONG 4B 188 | -H8 Reserved | - 10 x UNSIGNED CHAR 10B 189 |---------------------------| 190 | -P1 payload | - 191 ----------------------------- 192 */ 193 public: CPacket()194 CPacket() 195 { 196 m_PacketType = 0; 197 } ~CPacket()198 virtual ~CPacket() 199 { } 200 201 bool Send(int Socket, CAddress &Addr, unsigned int UID = XBMCClientUtils::GetUniqueIdentifier()) 202 { 203 if (m_Payload.size() == 0) 204 ConstructPayload(); 205 bool SendSuccessfull = true; 206 int NbrOfPackages = (m_Payload.size() / MAX_PAYLOAD_SIZE) + 1; 207 int Send = 0; 208 int Sent = 0; 209 int Left = m_Payload.size(); 210 for (int Package = 1; Package <= NbrOfPackages; Package++) 211 { 212 if (Left > MAX_PAYLOAD_SIZE) 213 { 214 Send = MAX_PAYLOAD_SIZE; 215 Left -= Send; 216 } 217 else 218 { 219 Send = Left; 220 Left = 0; 221 } 222 223 ConstructHeader(m_PacketType, NbrOfPackages, Package, Send, UID, m_Header); 224 char t[MAX_PACKET_SIZE]; 225 int i, j; 226 for (i = 0; i < 32; i++) 227 t[i] = m_Header[i]; 228 229 for (j = 0; j < Send; j++) 230 t[(32 + j)] = m_Payload[j + Sent]; 231 232 int rtn = sendto(Socket, t, (32 + Send), 0, Addr.GetAddress(), sizeof(struct sockaddr)); 233 234 if (rtn != (32 + Send)) 235 SendSuccessfull = false; 236 237 Sent += Send; 238 } 239 return SendSuccessfull; 240 } 241 protected: 242 char m_Header[HEADER_SIZE]; 243 unsigned short m_PacketType; 244 245 std::vector<char> m_Payload; 246 ConstructHeader(int PacketType,int NumberOfPackets,int CurrentPacket,unsigned short PayloadSize,unsigned int UniqueToken,char * Header)247 static void ConstructHeader(int PacketType, int NumberOfPackets, int CurrentPacket, unsigned short PayloadSize, unsigned int UniqueToken, char *Header) 248 { 249 sprintf(Header, "XBMC"); 250 for (int i = 4; i < HEADER_SIZE; i++) 251 Header[i] = 0; 252 Header[4] = MAJOR_VERSION; 253 Header[5] = MINOR_VERSION; 254 if (CurrentPacket == 1) 255 { 256 Header[6] = ((PacketType & 0xff00) >> 8); 257 Header[7] = (PacketType & 0x00ff); 258 } 259 else 260 { 261 Header[6] = ((PT_BLOB & 0xff00) >> 8); 262 Header[7] = (PT_BLOB & 0x00ff); 263 } 264 Header[8] = ((CurrentPacket & 0xff000000) >> 24); 265 Header[9] = ((CurrentPacket & 0x00ff0000) >> 16); 266 Header[10] = ((CurrentPacket & 0x0000ff00) >> 8); 267 Header[11] = (CurrentPacket & 0x000000ff); 268 269 Header[12] = ((NumberOfPackets & 0xff000000) >> 24); 270 Header[13] = ((NumberOfPackets & 0x00ff0000) >> 16); 271 Header[14] = ((NumberOfPackets & 0x0000ff00) >> 8); 272 Header[15] = (NumberOfPackets & 0x000000ff); 273 274 Header[16] = ((PayloadSize & 0xff00) >> 8); 275 Header[17] = (PayloadSize & 0x00ff); 276 277 Header[18] = ((UniqueToken & 0xff000000) >> 24); 278 Header[19] = ((UniqueToken & 0x00ff0000) >> 16); 279 Header[20] = ((UniqueToken & 0x0000ff00) >> 8); 280 Header[21] = (UniqueToken & 0x000000ff); 281 } 282 ConstructPayload()283 virtual void ConstructPayload() 284 { } 285 }; 286 287 class CPacketHELO : public CPacket 288 { 289 /************************************************************************/ 290 /* Payload format */ 291 /* %s - device name (max 128 chars) */ 292 /* %c - icontype ( 0=>NOICON, 1=>JPEG , 2=>PNG , 3=>GIF ) */ 293 /* %s - my port ( 0=>not listening ) */ 294 /* %d - reserved1 ( 0 ) */ 295 /* %d - reserved2 ( 0 ) */ 296 /* XX - imagedata ( can span multiple packets ) */ 297 /************************************************************************/ 298 private: 299 std::vector<char> m_DeviceName; 300 unsigned short m_IconType; 301 char *m_IconData; 302 unsigned short m_IconSize; 303 public: ConstructPayload()304 virtual void ConstructPayload() 305 { 306 m_Payload.clear(); 307 308 for (unsigned int i = 0; i < m_DeviceName.size(); i++) 309 m_Payload.push_back(m_DeviceName[i]); 310 311 m_Payload.push_back('\0'); 312 313 m_Payload.push_back((const char)m_IconType); 314 315 m_Payload.push_back(0); 316 m_Payload.push_back('\0'); 317 318 for (int j = 0; j < 8; j++) 319 m_Payload.push_back(0); 320 321 for (int ico = 0; ico < m_IconSize; ico++) 322 m_Payload.push_back(m_IconData[ico]); 323 } 324 CPacket()325 CPacketHELO(const char *DevName, unsigned short IconType, const char *IconFile = NULL) : CPacket() 326 { 327 m_PacketType = PT_HELO; 328 329 unsigned int len = strlen(DevName); 330 for (unsigned int i = 0; i < len; i++) 331 m_DeviceName.push_back(DevName[i]); 332 333 m_IconType = IconType; 334 335 if (IconType == ICON_NONE || IconFile == NULL) 336 { 337 m_IconData = NULL; 338 m_IconSize = 0; 339 return; 340 } 341 342 std::ifstream::pos_type size; 343 344 std::ifstream file (IconFile, std::ios::in|std::ios::binary|std::ios::ate); 345 if (file.is_open()) 346 { 347 size = file.tellg(); 348 m_IconData = new char[(unsigned int)size]; 349 file.seekg (0, std::ios::beg); 350 file.read (m_IconData, size); 351 file.close(); 352 m_IconSize = (unsigned int)size; 353 } 354 else 355 { 356 m_IconType = ICON_NONE; 357 m_IconSize = 0; 358 } 359 } 360 ~CPacketHELO()361 virtual ~CPacketHELO() 362 { 363 m_DeviceName.clear(); 364 delete[] m_IconData; 365 } 366 }; 367 368 class CPacketNOTIFICATION : public CPacket 369 { 370 /************************************************************************/ 371 /* Payload format: */ 372 /* %s - caption */ 373 /* %s - message */ 374 /* %c - icontype ( 0=>NOICON, 1=>JPEG , 2=>PNG , 3=>GIF ) */ 375 /* %d - reserved ( 0 ) */ 376 /* XX - imagedata ( can span multiple packets ) */ 377 /************************************************************************/ 378 private: 379 std::vector<char> m_Title; 380 std::vector<char> m_Message; 381 unsigned short m_IconType; 382 char *m_IconData; 383 unsigned short m_IconSize; 384 public: ConstructPayload()385 virtual void ConstructPayload() 386 { 387 m_Payload.clear(); 388 389 for (unsigned int i = 0; i < m_Title.size(); i++) 390 m_Payload.push_back(m_Title[i]); 391 392 m_Payload.push_back('\0'); 393 394 for (unsigned int i = 0; i < m_Message.size(); i++) 395 m_Payload.push_back(m_Message[i]); 396 397 m_Payload.push_back('\0'); 398 399 m_Payload.push_back((unsigned char)m_IconType); 400 401 for (int i = 0; i < 4; i++) 402 m_Payload.push_back(0); 403 404 for (int ico = 0; ico < m_IconSize; ico++) 405 m_Payload.push_back(m_IconData[ico]); 406 } 407 CPacket()408 CPacketNOTIFICATION(const char *Title, const char *Message, unsigned short IconType, const char *IconFile = NULL) : CPacket() 409 { 410 m_PacketType = PT_NOTIFICATION; 411 m_IconData = NULL; 412 m_IconSize = 0; 413 unsigned int len = 0; 414 if (Title != NULL) 415 { 416 len = strlen(Title); 417 for (unsigned int i = 0; i < len; i++) 418 m_Title.push_back(Title[i]); 419 } 420 421 if (Message != NULL) 422 { 423 len = strlen(Message); 424 for (unsigned int i = 0; i < len; i++) 425 m_Message.push_back(Message[i]); 426 } 427 m_IconType = IconType; 428 429 if (IconType == ICON_NONE || IconFile == NULL) 430 return; 431 432 std::ifstream::pos_type size; 433 434 std::ifstream file (IconFile, std::ios::in|std::ios::binary|std::ios::ate); 435 if (file.is_open()) 436 { 437 size = file.tellg(); 438 m_IconData = new char[(unsigned int)size]; 439 file.seekg (0, std::ios::beg); 440 file.read (m_IconData, size); 441 file.close(); 442 m_IconSize = (unsigned int)size; 443 } 444 else 445 m_IconType = ICON_NONE; 446 } 447 ~CPacketNOTIFICATION()448 virtual ~CPacketNOTIFICATION() 449 { 450 m_Title.clear(); 451 m_Message.clear(); 452 delete[] m_IconData; 453 } 454 }; 455 456 class CPacketBUTTON : public CPacket 457 { 458 /************************************************************************/ 459 /* Payload format */ 460 /* %i - button code */ 461 /* %i - flags 0x01 => use button map/name instead of code */ 462 /* 0x02 => btn down */ 463 /* 0x04 => btn up */ 464 /* 0x08 => use amount */ 465 /* 0x10 => queue event */ 466 /* 0x20 => do not repeat */ 467 /* 0x40 => virtual key */ 468 /* 0x40 => axis key */ 469 /* %i - amount ( 0 => 65k maps to -1 => 1 ) */ 470 /* %s - device map (case sensitive and required if flags & 0x01) */ 471 /* "KB" - Standard keyboard map */ 472 /* "XG" - Xbox Gamepad */ 473 /* "R1" - Xbox Remote */ 474 /* "R2" - Xbox Universal Remote */ 475 /* "LI:devicename" - valid LIRC device map where 'devicename' */ 476 /* is the actual name of the LIRC device */ 477 /* "JS<num>:joyname" - valid Joystick device map where */ 478 /* 'joyname' is the name specified in */ 479 /* the keymap. JS only supports button code */ 480 /* and not button name currently (!0x01). */ 481 /* %s - button name (required if flags & 0x01) */ 482 /************************************************************************/ 483 private: 484 std::vector<char> m_DeviceMap; 485 std::vector<char> m_Button; 486 unsigned short m_ButtonCode; 487 unsigned short m_Amount; 488 unsigned short m_Flags; 489 public: ConstructPayload()490 virtual void ConstructPayload() 491 { 492 m_Payload.clear(); 493 494 if (m_Button.size() != 0) 495 { 496 if (!(m_Flags & BTN_USE_NAME)) // If the BTN_USE_NAME isn't flagged for some reason 497 m_Flags |= BTN_USE_NAME; 498 m_ButtonCode = 0; 499 } 500 else 501 m_Button.clear(); 502 503 if (m_Amount > 0) 504 { 505 if (!(m_Flags & BTN_USE_AMOUNT)) 506 m_Flags |= BTN_USE_AMOUNT; 507 } 508 if (!((m_Flags & BTN_DOWN) || (m_Flags & BTN_UP))) //If none of them are tagged. 509 m_Flags |= BTN_DOWN; 510 511 m_Payload.push_back(((m_ButtonCode & 0xff00) >> 8)); 512 m_Payload.push_back( (m_ButtonCode & 0x00ff)); 513 514 m_Payload.push_back(((m_Flags & 0xff00) >> 8) ); 515 m_Payload.push_back( (m_Flags & 0x00ff)); 516 517 m_Payload.push_back(((m_Amount & 0xff00) >> 8) ); 518 m_Payload.push_back( (m_Amount & 0x00ff)); 519 520 521 for (unsigned int i = 0; i < m_DeviceMap.size(); i++) 522 m_Payload.push_back(m_DeviceMap[i]); 523 524 m_Payload.push_back('\0'); 525 526 for (unsigned int i = 0; i < m_Button.size(); i++) 527 m_Payload.push_back(m_Button[i]); 528 529 m_Payload.push_back('\0'); 530 } 531 CPacket()532 CPacketBUTTON(const char *Button, const char *DeviceMap, unsigned short Flags, unsigned short Amount = 0) : CPacket() 533 { 534 m_PacketType = PT_BUTTON; 535 m_Flags = Flags; 536 m_ButtonCode = 0; 537 m_Amount = Amount; 538 539 unsigned int len = strlen(DeviceMap); 540 for (unsigned int i = 0; i < len; i++) 541 m_DeviceMap.push_back(DeviceMap[i]); 542 543 len = strlen(Button); 544 for (unsigned int i = 0; i < len; i++) 545 m_Button.push_back(Button[i]); 546 } 547 CPacket()548 CPacketBUTTON(unsigned short ButtonCode, const char *DeviceMap, unsigned short Flags, unsigned short Amount = 0) : CPacket() 549 { 550 m_PacketType = PT_BUTTON; 551 m_Flags = Flags; 552 m_ButtonCode = ButtonCode; 553 m_Amount = Amount; 554 555 unsigned int len = strlen(DeviceMap); 556 for (unsigned int i = 0; i < len; i++) 557 m_DeviceMap.push_back(DeviceMap[i]); 558 } 559 CPacket()560 CPacketBUTTON(unsigned short ButtonCode, unsigned short Flags, unsigned short Amount = 0) : CPacket() 561 { 562 m_PacketType = PT_BUTTON; 563 m_Flags = Flags; 564 m_ButtonCode = ButtonCode; 565 m_Amount = Amount; 566 } 567 568 // Used to send a release event CPacketBUTTON()569 CPacketBUTTON() : CPacket() 570 { 571 m_PacketType = PT_BUTTON; 572 m_Flags = BTN_UP; 573 m_Amount = 0; 574 m_ButtonCode = 0; 575 } 576 ~CPacketBUTTON()577 virtual ~CPacketBUTTON() 578 { 579 m_DeviceMap.clear(); 580 m_Button.clear(); 581 } 582 GetFlags()583 inline unsigned short GetFlags() { return m_Flags; } GetButtonCode()584 inline unsigned short GetButtonCode() { return m_ButtonCode; } 585 }; 586 587 class CPacketPING : public CPacket 588 { 589 /************************************************************************/ 590 /* no payload */ 591 /************************************************************************/ 592 public: CPacketPING()593 CPacketPING() : CPacket() 594 { 595 m_PacketType = PT_PING; 596 } ~CPacketPING()597 virtual ~CPacketPING() 598 { } 599 }; 600 601 class CPacketBYE : public CPacket 602 { 603 /************************************************************************/ 604 /* no payload */ 605 /************************************************************************/ 606 public: CPacketBYE()607 CPacketBYE() : CPacket() 608 { 609 m_PacketType = PT_BYE; 610 } ~CPacketBYE()611 virtual ~CPacketBYE() 612 { } 613 }; 614 615 class CPacketMOUSE : public CPacket 616 { 617 /************************************************************************/ 618 /* Payload format */ 619 /* %c - flags */ 620 /* - 0x01 absolute position */ 621 /* %i - mousex (0-65535 => maps to screen width) */ 622 /* %i - mousey (0-65535 => maps to screen height) */ 623 /************************************************************************/ 624 private: 625 unsigned short m_X; 626 unsigned short m_Y; 627 unsigned char m_Flag; 628 public: 629 CPacketMOUSE(int X, int Y, unsigned char Flag = MS_ABSOLUTE) 630 { 631 m_PacketType = PT_MOUSE; 632 m_Flag = Flag; 633 m_X = X; 634 m_Y = Y; 635 } 636 ConstructPayload()637 virtual void ConstructPayload() 638 { 639 m_Payload.clear(); 640 641 m_Payload.push_back(m_Flag); 642 643 m_Payload.push_back(((m_X & 0xff00) >> 8)); 644 m_Payload.push_back( (m_X & 0x00ff)); 645 646 m_Payload.push_back(((m_Y & 0xff00) >> 8)); 647 m_Payload.push_back( (m_Y & 0x00ff)); 648 } 649 ~CPacketMOUSE()650 virtual ~CPacketMOUSE() 651 { } 652 }; 653 654 class CPacketLOG : public CPacket 655 { 656 /************************************************************************/ 657 /* Payload format */ 658 /* %c - log type */ 659 /* %s - message */ 660 /************************************************************************/ 661 private: 662 std::vector<char> m_Message; 663 unsigned char m_LogLevel; 664 bool m_AutoPrintf; 665 public: 666 CPacketLOG(int LogLevel, const char *Message, bool AutoPrintf = true) 667 { 668 m_PacketType = PT_LOG; 669 670 unsigned int len = strlen(Message); 671 for (unsigned int i = 0; i < len; i++) 672 m_Message.push_back(Message[i]); 673 674 m_LogLevel = LogLevel; 675 m_AutoPrintf = AutoPrintf; 676 } 677 ConstructPayload()678 virtual void ConstructPayload() 679 { 680 m_Payload.clear(); 681 682 m_Payload.push_back( (m_LogLevel & 0x00ff) ); 683 684 if (m_AutoPrintf) 685 { 686 char* str=&m_Message[0]; 687 printf("%s\n", str); 688 } 689 for (unsigned int i = 0; i < m_Message.size(); i++) 690 m_Payload.push_back(m_Message[i]); 691 692 m_Payload.push_back('\0'); 693 } 694 ~CPacketLOG()695 virtual ~CPacketLOG() 696 { } 697 }; 698 699 class CPacketACTION : public CPacket 700 { 701 /************************************************************************/ 702 /* Payload format */ 703 /* %c - action type */ 704 /* %s - action message */ 705 /************************************************************************/ 706 private: 707 unsigned char m_ActionType; 708 std::vector<char> m_Action; 709 public: 710 CPacketACTION(const char *Action, unsigned char ActionType = ACTION_EXECBUILTIN) 711 { 712 m_PacketType = PT_ACTION; 713 714 m_ActionType = ActionType; 715 unsigned int len = strlen(Action); 716 for (unsigned int i = 0; i < len; i++) 717 m_Action.push_back(Action[i]); 718 } 719 ConstructPayload()720 virtual void ConstructPayload() 721 { 722 m_Payload.clear(); 723 724 m_Payload.push_back(m_ActionType); 725 for (unsigned int i = 0; i < m_Action.size(); i++) 726 m_Payload.push_back(m_Action[i]); 727 728 m_Payload.push_back('\0'); 729 } 730 ~CPacketACTION()731 virtual ~CPacketACTION() 732 { } 733 }; 734 735 class CXBMCClient 736 { 737 private: 738 CAddress m_Addr; 739 int m_Socket; 740 unsigned int m_UID; 741 public: 742 CXBMCClient(const char *IP = "127.0.0.1", int Port = 9777, int Socket = -1, unsigned int UID = 0) 743 { 744 m_Addr = CAddress(IP, Port); 745 if (Socket == -1) 746 m_Socket = socket(AF_INET, SOCK_DGRAM, 0); 747 else 748 m_Socket = Socket; 749 750 if (UID) 751 m_UID = UID; 752 else 753 m_UID = XBMCClientUtils::GetUniqueIdentifier(); 754 } 755 756 void SendNOTIFICATION(const char *Title, const char *Message, unsigned short IconType, const char *IconFile = NULL) 757 { 758 if (m_Socket < 0) 759 return; 760 761 CPacketNOTIFICATION notification(Title, Message, IconType, IconFile); 762 notification.Send(m_Socket, m_Addr, m_UID); 763 } 764 765 void SendHELO(const char *DevName, unsigned short IconType, const char *IconFile = NULL) 766 { 767 if (m_Socket < 0) 768 return; 769 770 CPacketHELO helo(DevName, IconType, IconFile); 771 helo.Send(m_Socket, m_Addr, m_UID); 772 } 773 774 void SendButton(const char *Button, const char *DeviceMap, unsigned short Flags, unsigned short Amount = 0) 775 { 776 if (m_Socket < 0) 777 return; 778 779 CPacketBUTTON button(Button, DeviceMap, Flags, Amount); 780 button.Send(m_Socket, m_Addr, m_UID); 781 } 782 783 void SendButton(unsigned short ButtonCode, const char *DeviceMap, unsigned short Flags, unsigned short Amount = 0) 784 { 785 if (m_Socket < 0) 786 return; 787 788 CPacketBUTTON button(ButtonCode, DeviceMap, Flags, Amount); 789 button.Send(m_Socket, m_Addr, m_UID); 790 } 791 792 void SendButton(unsigned short ButtonCode, unsigned Flags, unsigned short Amount = 0) 793 { 794 if (m_Socket < 0) 795 return; 796 797 CPacketBUTTON button(ButtonCode, Flags, Amount); 798 button.Send(m_Socket, m_Addr, m_UID); 799 } 800 801 void SendMOUSE(int X, int Y, unsigned char Flag = MS_ABSOLUTE) 802 { 803 if (m_Socket < 0) 804 return; 805 806 CPacketMOUSE mouse(X, Y, Flag); 807 mouse.Send(m_Socket, m_Addr, m_UID); 808 } 809 810 void SendLOG(int LogLevel, const char *Message, bool AutoPrintf = true) 811 { 812 if (m_Socket < 0) 813 return; 814 815 CPacketLOG log(LogLevel, Message, AutoPrintf); 816 log.Send(m_Socket, m_Addr, m_UID); 817 } 818 819 void SendACTION(const char *ActionMessage, int ActionType = ACTION_EXECBUILTIN) 820 { 821 if (m_Socket < 0) 822 return; 823 824 CPacketACTION action(ActionMessage, ActionType); 825 action.Send(m_Socket, m_Addr, m_UID); 826 } 827 }; 828 829 #endif 830 831