|
|
1.1 ! root 1: // net_ser.c ! 2: ! 3: #include "quakedef.h" ! 4: #include "net_ser.h" ! 5: #include "dosisms.h" ! 6: #include "crc.h" ! 7: ! 8: #include "net_comx.c" ! 9: ! 10: // serial protocol ! 11: ! 12: #define SERIAL_PROTOCOL_VERSION 3 ! 13: ! 14: // The serial protocol is message oriented. The high level message format is ! 15: // a one byte message type (MTYPE_xxx), data, and a 16-bit checksum. All ! 16: // multi-byte fields are sent in network byte order. There are currently 4 ! 17: // MTYPEs defined. Their formats are as follows: ! 18: // ! 19: // MTYPE_RELIABLE sequence data_length data checksum eom ! 20: // MTYPE_UNRELIABLE sequence data_length data checksum eom ! 21: // MTYPE_ACK sequence checksum eom ! 22: // MTYPE_CONTROL data_length data checksum eom ! 23: // ! 24: // sequence is an 8-bit unsigned value starting from 0 ! 25: // data_length is a 16-bit unsigned value; it is the length of the data only ! 26: // the checksum is a 16-bit value. the CRC formula used is defined in crc.h. ! 27: // the checksum covers the entire messages, excluding itself ! 28: // eom is a special 2 byte sequence used to mark the End Of Message. This is ! 29: // needed for error recovery. ! 30: // ! 31: // A lot of behavior is based on knowledge of the upper level Quake network ! 32: // layer. For example, only one reliable message can be outstanding (pending ! 33: // reception of an MTYPE_ACK) at a time. ! 34: // ! 35: // The low level routines used to communicate with the modem are not part of ! 36: // this protocol. ! 37: // ! 38: // The CONTROL messages are only used for session establishment. They are ! 39: // not reliable or sequenced. ! 40: ! 41: #define MTYPE_RELIABLE 0x01 ! 42: #define MTYPE_UNRELIABLE 0x02 ! 43: #define MTYPE_CONTROL 0x03 ! 44: #define MTYPE_ACK 0x04 ! 45: #define MTYPE_CLIENT 0x80 ! 46: ! 47: #define ESCAPE_COMMAND 0xe0 ! 48: #define ESCAPE_EOM 0x19 ! 49: ! 50: static qboolean listening = false; ! 51: ! 52: ! 53: typedef struct SerialLine_s ! 54: { ! 55: struct SerialLine_s *next; ! 56: qsocket_t *sock; ! 57: int lengthStated; ! 58: int lengthFound; ! 59: int tty; ! 60: qboolean connected; ! 61: qboolean connecting; ! 62: qboolean client; ! 63: double connect_time; ! 64: unsigned short crcStated; ! 65: unsigned short crcValue; ! 66: byte currState; ! 67: byte prevState; ! 68: byte mtype; ! 69: byte sequence; ! 70: } SerialLine; ! 71: ! 72: #define STATE_READY 0 ! 73: #define STATE_SEQUENCE 1 ! 74: #define STATE_LENGTH1 2 ! 75: #define STATE_LENGTH2 3 ! 76: #define STATE_DATA 4 ! 77: #define STATE_CRC1 5 ! 78: #define STATE_CRC2 6 ! 79: #define STATE_EOM 7 ! 80: #define STATE_ESCAPE 8 ! 81: #define STATE_ABORT 9 ! 82: ! 83: SerialLine serialLine[NUM_COM_PORTS]; ! 84: ! 85: int myDriverLevel; ! 86: ! 87: static void Serial_SendACK (SerialLine *p, byte sequence); ! 88: ! 89: ! 90: static void ResetSerialLineProtocol (SerialLine *p) ! 91: { ! 92: p->connected = false; ! 93: p->connecting = false; ! 94: p->currState = STATE_READY; ! 95: p->prevState = STATE_READY; ! 96: p->lengthFound = 0; ! 97: } ! 98: ! 99: ! 100: static int ProcessInQueue(SerialLine *p) ! 101: { ! 102: int b; ! 103: ! 104: while (1) ! 105: { ! 106: b = TTY_ReadByte(p->tty); ! 107: if (b == ERR_TTY_NODATA) ! 108: break; ! 109: ! 110: if (b == ERR_TTY_LINE_STATUS) ! 111: { ! 112: p->currState = STATE_ABORT; ! 113: continue; ! 114: } ! 115: if (b == ERR_TTY_MODEM_STATUS) ! 116: { ! 117: p->currState = STATE_ABORT; ! 118: return -1; ! 119: } ! 120: ! 121: if (b == ESCAPE_COMMAND) ! 122: if (p->currState != STATE_ESCAPE) ! 123: { ! 124: p->prevState = p->currState; ! 125: p->currState = STATE_ESCAPE; ! 126: continue; ! 127: } ! 128: ! 129: if (p->currState == STATE_ESCAPE) ! 130: { ! 131: if (b == ESCAPE_EOM) ! 132: { ! 133: if (p->prevState == STATE_ABORT) ! 134: { ! 135: p->currState = STATE_READY; ! 136: p->lengthFound = 0; ! 137: continue; ! 138: } ! 139: ! 140: if (p->prevState != STATE_EOM) ! 141: { ! 142: p->currState = STATE_READY; ! 143: p->lengthFound = 0; ! 144: Con_DPrintf("Serial: premature EOM\n"); ! 145: continue; ! 146: } ! 147: ! 148: switch (p->mtype) ! 149: { ! 150: case MTYPE_RELIABLE: ! 151: Con_DPrintf("Serial: sending ack %u\n", p->sequence); ! 152: Serial_SendACK (p, p->sequence); ! 153: if (p->sequence == p->sock->receiveSequence) ! 154: { ! 155: p->sock->receiveSequence = (p->sequence + 1) & 0xff; ! 156: p->sock->receiveMessageLength += p->lengthFound; ! 157: } ! 158: else ! 159: Con_DPrintf("Serial: reliable out of order; got %u wanted %u\n", p->sequence, p->sock->receiveSequence); ! 160: break; ! 161: ! 162: case MTYPE_UNRELIABLE: ! 163: p->sock->unreliableReceiveSequence = (p->sequence + 1) & 0xff; ! 164: p->sock->receiveMessageLength += p->lengthFound; ! 165: break; ! 166: ! 167: case MTYPE_ACK: ! 168: Con_DPrintf("Serial: got ack %u\n", p->sequence); ! 169: if (p->sequence == p->sock->sendSequence) ! 170: { ! 171: p->sock->sendSequence = (p->sock->sendSequence + 1) & 0xff; ! 172: p->sock->canSend = true; ! 173: } ! 174: else ! 175: Con_DPrintf("Serial: ack out of order; got %u wanted %u\n",p->sequence, p->sock->sendSequence); ! 176: break; ! 177: ! 178: case MTYPE_CONTROL: ! 179: p->sock->receiveMessageLength += p->lengthFound; ! 180: break; ! 181: } ! 182: ! 183: p->currState = STATE_READY; ! 184: p->lengthFound = 0; ! 185: continue; ! 186: } ! 187: ! 188: ! 189: if (b != ESCAPE_COMMAND) ! 190: { ! 191: p->currState = STATE_ABORT; ! 192: Con_DPrintf("Serial: Bad escape sequence\n"); ! 193: continue; ! 194: } ! 195: ! 196: // b == ESCAPE_COMMAND ! 197: p->currState = p->prevState; ! 198: } ! 199: ! 200: p->prevState = p->currState; ! 201: ! 202: //DEBUG ! 203: if (p->sock->receiveMessageLength + p->lengthFound > NET_MAXMESSAGE) ! 204: { ! 205: Con_DPrintf("Serial blew out receive buffer: %u\n", p->sock->receiveMessageLength + p->lengthFound); ! 206: p->currState = STATE_ABORT; ! 207: } ! 208: if (p->sock->receiveMessageLength + p->lengthFound == NET_MAXMESSAGE) ! 209: { ! 210: Con_DPrintf("Serial hit receive buffer limit: %u\n", p->sock->receiveMessageLength + p->lengthFound); ! 211: p->currState = STATE_ABORT; ! 212: } ! 213: //end DEBUG ! 214: ! 215: switch (p->currState) ! 216: { ! 217: case STATE_READY: ! 218: CRC_Init(&p->crcValue); ! 219: CRC_ProcessByte(&p->crcValue, b); ! 220: if (p->client) ! 221: { ! 222: if ((b & MTYPE_CLIENT) != 0) ! 223: { ! 224: p->currState = STATE_ABORT; ! 225: Con_DPrintf("Serial: client got own message\n"); ! 226: break; ! 227: } ! 228: } ! 229: else ! 230: { ! 231: if ((b & MTYPE_CLIENT) == 0) ! 232: { ! 233: p->currState = STATE_ABORT; ! 234: Con_DPrintf("Serial: server got own message\n"); ! 235: break; ! 236: } ! 237: b &= 0x7f; ! 238: } ! 239: p->mtype = b; ! 240: if (b != MTYPE_CONTROL) ! 241: p->currState = STATE_SEQUENCE; ! 242: else ! 243: p->currState = STATE_LENGTH1; ! 244: if (p->mtype < MTYPE_ACK) ! 245: { ! 246: p->sock->receiveMessage[p->sock->receiveMessageLength] = b; ! 247: p->lengthFound++; ! 248: } ! 249: break; ! 250: ! 251: case STATE_SEQUENCE: ! 252: p->sequence = b; ! 253: CRC_ProcessByte(&p->crcValue, b); ! 254: if (p->mtype != MTYPE_ACK) ! 255: p->currState = STATE_LENGTH1; ! 256: else ! 257: p->currState = STATE_CRC1; ! 258: break; ! 259: ! 260: case STATE_LENGTH1: ! 261: p->lengthStated = b * 256; ! 262: CRC_ProcessByte(&p->crcValue, b); ! 263: p->currState = STATE_LENGTH2; ! 264: break; ! 265: ! 266: case STATE_LENGTH2: ! 267: p->lengthStated += b; ! 268: CRC_ProcessByte(&p->crcValue, b); ! 269: if (p->mtype == MTYPE_RELIABLE && p->lengthStated > MAX_MSGLEN) ! 270: { ! 271: p->currState = STATE_ABORT; ! 272: Con_DPrintf("Serial: bad reliable message length %u\n", p->lengthStated); ! 273: } ! 274: else if (p->mtype == MTYPE_UNRELIABLE && p->lengthStated > MAX_DATAGRAM) ! 275: { ! 276: p->currState = STATE_ABORT; ! 277: Con_DPrintf("Serial: bad unreliable message length %u\n", p->lengthStated); ! 278: } ! 279: else ! 280: { ! 281: p->currState = STATE_DATA; ! 282: if (p->mtype < MTYPE_ACK) ! 283: { ! 284: *(short *)&p->sock->receiveMessage [p->sock->receiveMessageLength + 1] = p->lengthStated; ! 285: p->lengthFound += 2; ! 286: } ! 287: } ! 288: break; ! 289: ! 290: case STATE_DATA: ! 291: p->sock->receiveMessage[p->sock->receiveMessageLength + p->lengthFound] = b; ! 292: p->lengthFound++; ! 293: CRC_ProcessByte(&p->crcValue, b); ! 294: if (p->lengthFound == p->lengthStated + 3) ! 295: p->currState = STATE_CRC1; ! 296: break; ! 297: ! 298: case STATE_CRC1: ! 299: p->crcStated = b * 256; ! 300: p->currState = STATE_CRC2; ! 301: break; ! 302: ! 303: case STATE_CRC2: ! 304: p->crcStated += b; ! 305: if (p->crcStated == CRC_Value(p->crcValue)) ! 306: { ! 307: p->currState = STATE_EOM; ! 308: } ! 309: else ! 310: { ! 311: p->currState = STATE_ABORT; ! 312: Con_DPrintf("Serial: Bad crc\n"); ! 313: } ! 314: break; ! 315: ! 316: case STATE_EOM: ! 317: p->currState = STATE_ABORT; ! 318: Con_DPrintf("Serial: Bad message format\n"); ! 319: break; ! 320: ! 321: case STATE_ABORT: ! 322: break; ! 323: } ! 324: } ! 325: return 0; ! 326: } ! 327: ! 328: ! 329: int Serial_Init (void) ! 330: { ! 331: int n; ! 332: ! 333: if (COM_CheckParm("-nolan")) ! 334: return -1; ! 335: if (COM_CheckParm ("-noserial")) ! 336: return -1; ! 337: ! 338: myDriverLevel = net_driverlevel; ! 339: ! 340: if (TTY_Init()) ! 341: return -1; ! 342: ! 343: for (n = 0; n < NUM_COM_PORTS; n++) ! 344: { ! 345: serialLine[n].tty = TTY_Open(n); ! 346: ResetSerialLineProtocol (&serialLine[n]); ! 347: } ! 348: ! 349: Con_Printf("Serial driver initialized\n"); ! 350: serialAvailable = true; ! 351: ! 352: return 0; ! 353: } ! 354: ! 355: ! 356: void Serial_Shutdown (void) ! 357: { ! 358: int n; ! 359: ! 360: for (n = 0; n < NUM_COM_PORTS; n++) ! 361: { ! 362: if (serialLine[n].connected) ! 363: Serial_Close(serialLine[n].sock); ! 364: } ! 365: ! 366: TTY_Shutdown(); ! 367: } ! 368: ! 369: ! 370: void Serial_Listen (qboolean state) ! 371: { ! 372: listening = state; ! 373: } ! 374: ! 375: ! 376: qboolean Serial_CanSendMessage (qsocket_t *sock) ! 377: { ! 378: return sock->canSend; ! 379: } ! 380: ! 381: ! 382: qboolean Serial_CanSendUnreliableMessage (qsocket_t *sock) ! 383: { ! 384: return TTY_OutputQueueIsEmpty(((SerialLine *)sock->driverdata)->tty); ! 385: } ! 386: ! 387: ! 388: int Serial_SendMessage (qsocket_t *sock, sizebuf_t *message) ! 389: { ! 390: SerialLine *p; ! 391: int n; ! 392: unsigned short crc; ! 393: byte b; ! 394: ! 395: p = (SerialLine *)sock->driverdata; ! 396: CRC_Init (&crc); ! 397: ! 398: // message type ! 399: b = MTYPE_RELIABLE; ! 400: if (p->client) ! 401: b |= MTYPE_CLIENT; ! 402: TTY_WriteByte(p->tty, b); ! 403: CRC_ProcessByte (&crc, b); ! 404: ! 405: // sequence ! 406: b = p->sock->sendSequence; ! 407: TTY_WriteByte(p->tty, b); ! 408: if (b == ESCAPE_COMMAND) ! 409: TTY_WriteByte(p->tty, b); ! 410: CRC_ProcessByte (&crc, b); ! 411: ! 412: // data length ! 413: b = message->cursize >> 8; ! 414: TTY_WriteByte(p->tty, b); ! 415: if (b == ESCAPE_COMMAND) ! 416: TTY_WriteByte(p->tty, b); ! 417: CRC_ProcessByte (&crc, b); ! 418: b = message->cursize & 0xff; ! 419: TTY_WriteByte(p->tty, b); ! 420: if (b == ESCAPE_COMMAND) ! 421: TTY_WriteByte(p->tty, b); ! 422: CRC_ProcessByte (&crc, b); ! 423: ! 424: // data ! 425: for (n = 0; n < message->cursize; n++) ! 426: { ! 427: b = message->data[n]; ! 428: TTY_WriteByte(p->tty, b); ! 429: if (b == ESCAPE_COMMAND) ! 430: TTY_WriteByte(p->tty, b); ! 431: CRC_ProcessByte (&crc, b); ! 432: } ! 433: ! 434: // checksum ! 435: b = CRC_Value (crc) >> 8; ! 436: TTY_WriteByte(p->tty, b); ! 437: if (b == ESCAPE_COMMAND) ! 438: TTY_WriteByte(p->tty, b); ! 439: b = CRC_Value (crc) & 0xff; ! 440: TTY_WriteByte(p->tty, b); ! 441: if (b == ESCAPE_COMMAND) ! 442: TTY_WriteByte(p->tty, b); ! 443: ! 444: // end of message ! 445: TTY_WriteByte(p->tty, ESCAPE_COMMAND); ! 446: TTY_WriteByte(p->tty, ESCAPE_EOM); ! 447: ! 448: TTY_Flush(p->tty); ! 449: ! 450: // mark sock as busy and save the message for possible retransmit ! 451: sock->canSend = false; ! 452: Q_memcpy(sock->sendMessage, message->data, message->cursize); ! 453: sock->sendMessageLength = message->cursize; ! 454: sock->lastSendTime = net_time; ! 455: ! 456: return 1; ! 457: } ! 458: ! 459: ! 460: static void ReSendMessage (qsocket_t *sock) ! 461: { ! 462: sizebuf_t temp; ! 463: ! 464: Con_DPrintf("Serial: re-sending reliable\n"); ! 465: temp.data = sock->sendMessage; ! 466: temp.maxsize = sock->sendMessageLength; ! 467: temp.cursize = sock->sendMessageLength; ! 468: Serial_SendMessage (sock, &temp); ! 469: } ! 470: ! 471: ! 472: int Serial_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *message) ! 473: { ! 474: SerialLine *p; ! 475: int n; ! 476: unsigned short crc; ! 477: byte b; ! 478: ! 479: p = (SerialLine *)sock->driverdata; ! 480: ! 481: if (!TTY_OutputQueueIsEmpty(p->tty)) ! 482: { ! 483: TTY_Flush(p->tty); ! 484: return 1; ! 485: } ! 486: ! 487: CRC_Init (&crc); ! 488: ! 489: // message type ! 490: b = MTYPE_UNRELIABLE; ! 491: if (p->client) ! 492: b |= MTYPE_CLIENT; ! 493: TTY_WriteByte(p->tty, b); ! 494: CRC_ProcessByte (&crc, b); ! 495: ! 496: // sequence ! 497: b = p->sock->unreliableSendSequence; ! 498: p->sock->unreliableSendSequence = (b + 1) & 0xff; ! 499: TTY_WriteByte(p->tty, b); ! 500: if (b == ESCAPE_COMMAND) ! 501: TTY_WriteByte(p->tty, b); ! 502: CRC_ProcessByte (&crc, b); ! 503: ! 504: // data length ! 505: b = message->cursize >> 8; ! 506: TTY_WriteByte(p->tty, b); ! 507: if (b == ESCAPE_COMMAND) ! 508: TTY_WriteByte(p->tty, b); ! 509: CRC_ProcessByte (&crc, b); ! 510: b = message->cursize & 0xff; ! 511: TTY_WriteByte(p->tty, b); ! 512: if (b == ESCAPE_COMMAND) ! 513: TTY_WriteByte(p->tty, b); ! 514: CRC_ProcessByte (&crc, b); ! 515: ! 516: // data ! 517: for (n = 0; n < message->cursize; n++) ! 518: { ! 519: b = message->data[n]; ! 520: TTY_WriteByte(p->tty, b); ! 521: if (b == ESCAPE_COMMAND) ! 522: TTY_WriteByte(p->tty, b); ! 523: CRC_ProcessByte (&crc, b); ! 524: } ! 525: ! 526: // checksum ! 527: b = CRC_Value (crc) >> 8; ! 528: TTY_WriteByte(p->tty, b); ! 529: if (b == ESCAPE_COMMAND) ! 530: TTY_WriteByte(p->tty, b); ! 531: b = CRC_Value (crc) & 0xff; ! 532: TTY_WriteByte(p->tty, b); ! 533: if (b == ESCAPE_COMMAND) ! 534: TTY_WriteByte(p->tty, b); ! 535: ! 536: // end of message ! 537: TTY_WriteByte(p->tty, ESCAPE_COMMAND); ! 538: TTY_WriteByte(p->tty, ESCAPE_EOM); ! 539: ! 540: TTY_Flush(p->tty); ! 541: ! 542: return 1; ! 543: } ! 544: ! 545: ! 546: static void Serial_SendACK (SerialLine *p, byte sequence) ! 547: { ! 548: unsigned short crc; ! 549: byte b; ! 550: ! 551: CRC_Init (&crc); ! 552: ! 553: // message type ! 554: b = MTYPE_ACK; ! 555: if (p->client) ! 556: b |= MTYPE_CLIENT; ! 557: TTY_WriteByte(p->tty, b); ! 558: CRC_ProcessByte (&crc, b); ! 559: ! 560: // sequence ! 561: b = sequence; ! 562: TTY_WriteByte(p->tty, b); ! 563: if (b == ESCAPE_COMMAND) ! 564: TTY_WriteByte(p->tty, b); ! 565: CRC_ProcessByte (&crc, b); ! 566: ! 567: // checksum ! 568: b = CRC_Value (crc) >> 8; ! 569: TTY_WriteByte(p->tty, b); ! 570: if (b == ESCAPE_COMMAND) ! 571: TTY_WriteByte(p->tty, b); ! 572: b = CRC_Value (crc) & 0xff; ! 573: TTY_WriteByte(p->tty, b); ! 574: if (b == ESCAPE_COMMAND) ! 575: TTY_WriteByte(p->tty, b); ! 576: ! 577: // end of message ! 578: TTY_WriteByte(p->tty, ESCAPE_COMMAND); ! 579: TTY_WriteByte(p->tty, ESCAPE_EOM); ! 580: ! 581: TTY_Flush(p->tty); ! 582: } ! 583: ! 584: ! 585: static void Serial_SendControlMessage (SerialLine *p, sizebuf_t *message) ! 586: { ! 587: unsigned short crc; ! 588: int n; ! 589: byte b; ! 590: ! 591: CRC_Init (&crc); ! 592: ! 593: // message type ! 594: b = MTYPE_CONTROL; ! 595: if (p->client) ! 596: b |= MTYPE_CLIENT; ! 597: TTY_WriteByte(p->tty, b); ! 598: CRC_ProcessByte (&crc, b); ! 599: ! 600: // data length ! 601: b = message->cursize >> 8; ! 602: TTY_WriteByte(p->tty, b); ! 603: if (b == ESCAPE_COMMAND) ! 604: TTY_WriteByte(p->tty, b); ! 605: CRC_ProcessByte (&crc, b); ! 606: b = message->cursize & 0xff; ! 607: TTY_WriteByte(p->tty, b); ! 608: if (b == ESCAPE_COMMAND) ! 609: TTY_WriteByte(p->tty, b); ! 610: CRC_ProcessByte (&crc, b); ! 611: ! 612: // data ! 613: for (n = 0; n < message->cursize; n++) ! 614: { ! 615: b = message->data[n]; ! 616: TTY_WriteByte(p->tty, b); ! 617: if (b == ESCAPE_COMMAND) ! 618: TTY_WriteByte(p->tty, b); ! 619: CRC_ProcessByte (&crc, b); ! 620: } ! 621: ! 622: // checksum ! 623: b = CRC_Value (crc) >> 8; ! 624: TTY_WriteByte(p->tty, b); ! 625: if (b == ESCAPE_COMMAND) ! 626: TTY_WriteByte(p->tty, b); ! 627: b = CRC_Value (crc) & 0xff; ! 628: TTY_WriteByte(p->tty, b); ! 629: if (b == ESCAPE_COMMAND) ! 630: TTY_WriteByte(p->tty, b); ! 631: ! 632: // end of message ! 633: TTY_WriteByte(p->tty, ESCAPE_COMMAND); ! 634: TTY_WriteByte(p->tty, ESCAPE_EOM); ! 635: ! 636: TTY_Flush(p->tty); ! 637: } ! 638: ! 639: ! 640: static int _Serial_GetMessage (SerialLine *p) ! 641: { ! 642: byte ret; ! 643: short length; ! 644: ! 645: if (ProcessInQueue(p)) ! 646: return -1; ! 647: ! 648: if (p->sock->receiveMessageLength == 0) ! 649: return 0; ! 650: ! 651: ret = p->sock->receiveMessage[0]; ! 652: length = *(short *)&p->sock->receiveMessage[1]; ! 653: if (ret == MTYPE_CONTROL) ! 654: ret = 1; ! 655: ! 656: SZ_Clear (&net_message); ! 657: SZ_Write (&net_message, &p->sock->receiveMessage[3], length); ! 658: ! 659: length += 3; ! 660: p->sock->receiveMessageLength -= length; ! 661: ! 662: if (p->sock->receiveMessageLength + p->lengthFound) ! 663: Q_memcpy(p->sock->receiveMessage, &p->sock->receiveMessage[length], p->sock->receiveMessageLength + p->lengthFound); ! 664: ! 665: return ret; ! 666: } ! 667: ! 668: int Serial_GetMessage (qsocket_t *sock) ! 669: { ! 670: SerialLine *p; ! 671: int ret; ! 672: ! 673: p = (SerialLine *)sock->driverdata; ! 674: ! 675: ret = _Serial_GetMessage (p); ! 676: ! 677: if (ret == 1) ! 678: messagesReceived++; ! 679: ! 680: if (!sock->canSend) ! 681: if ((net_time - sock->lastSendTime) > 1.0) ! 682: { ! 683: ReSendMessage (sock); ! 684: sock->lastSendTime = net_time; ! 685: } ! 686: ! 687: return ret; ! 688: } ! 689: ! 690: ! 691: void Serial_Close (qsocket_t *sock) ! 692: { ! 693: SerialLine *p = (SerialLine *)sock->driverdata; ! 694: TTY_Close(p->tty); ! 695: ResetSerialLineProtocol (p); ! 696: } ! 697: ! 698: ! 699: char *com_types[] = {"direct", "modem"}; ! 700: unsigned com_bauds[] = {9600, 14400, 19200, 28800, 57600}; ! 701: ! 702: void Serial_SearchForHosts (qboolean xmit) ! 703: { ! 704: int n; ! 705: SerialLine *p; ! 706: ! 707: if (sv.active) ! 708: return; ! 709: ! 710: if (hostCacheCount == HOSTCACHESIZE) ! 711: return; ! 712: ! 713: // see if we've already answered ! 714: for (n = 0; n < hostCacheCount; n++) ! 715: if (Q_strcmp (hostcache[n].cname, "#") == 0) ! 716: return; ! 717: ! 718: for (n = 0; n < NUM_COM_PORTS; n++) ! 719: if (TTY_IsEnabled(n)) ! 720: break; ! 721: if (n == NUM_COM_PORTS) ! 722: return; ! 723: p = &serialLine[n]; ! 724: ! 725: if (TTY_IsModem(p->tty)) ! 726: return; ! 727: ! 728: sprintf(hostcache[hostCacheCount].name, "COM%u", n+1); ! 729: Q_strcpy(hostcache[hostCacheCount].map, ""); ! 730: hostcache[hostCacheCount].users = 0; ! 731: hostcache[hostCacheCount].maxusers = 0; ! 732: hostcache[hostCacheCount].driver = net_driverlevel; ! 733: Q_strcpy(hostcache[hostCacheCount].cname, "#"); ! 734: hostCacheCount++; ! 735: ! 736: return; ! 737: } ! 738: ! 739: ! 740: static qsocket_t *_Serial_Connect (char *host, SerialLine *p) ! 741: { ! 742: int ret; ! 743: double start_time; ! 744: double last_time; ! 745: ! 746: p->client = true; ! 747: if (TTY_Connect(p->tty, host)) ! 748: return NULL; ! 749: ! 750: p->sock = NET_NewQSocket (); ! 751: p->sock->driver = myDriverLevel; ! 752: if (p->sock == NULL) ! 753: { ! 754: Con_Printf("No sockets available\n"); ! 755: return NULL; ! 756: } ! 757: p->sock->driverdata = p; ! 758: ! 759: // send the connection request ! 760: start_time = SetNetTime(); ! 761: last_time = 0.0; ! 762: ! 763: SZ_Clear(&net_message); ! 764: MSG_WriteByte(&net_message, CCREQ_CONNECT); ! 765: MSG_WriteString(&net_message, "QUAKE"); ! 766: do ! 767: { ! 768: SetNetTime(); ! 769: if ((net_time - last_time) >= 1.0) ! 770: { ! 771: Serial_SendControlMessage (p, &net_message); ! 772: last_time = net_time; ! 773: Con_Printf("trying...\n"); SCR_UpdateScreen (); ! 774: } ! 775: ret = _Serial_GetMessage (p); ! 776: } ! 777: while (ret == 0 && (net_time - start_time) < 5.0); ! 778: ! 779: if (ret == 0) ! 780: { ! 781: Con_Printf("Unable to connect, no response\n"); ! 782: goto ErrorReturn; ! 783: } ! 784: ! 785: if (ret == -1) ! 786: { ! 787: Con_Printf("Connection request error\n"); ! 788: goto ErrorReturn; ! 789: } ! 790: ! 791: MSG_BeginReading (); ! 792: ret = MSG_ReadByte(); ! 793: if (ret == CCREP_REJECT) ! 794: { ! 795: Con_Printf(MSG_ReadString()); ! 796: goto ErrorReturn; ! 797: } ! 798: if (ret != CCREP_ACCEPT) ! 799: { ! 800: Con_Printf("Unknown connection response\n"); ! 801: goto ErrorReturn; ! 802: } ! 803: ! 804: p->connected = true; ! 805: p->sock->lastMessageTime = net_time; ! 806: ! 807: Con_Printf ("Connection accepted\n"); ! 808: ! 809: return p->sock; ! 810: ! 811: ErrorReturn: ! 812: TTY_Disconnect(p->tty); ! 813: return NULL; ! 814: } ! 815: ! 816: qsocket_t *Serial_Connect (char *host) ! 817: { ! 818: int n; ! 819: qsocket_t *ret = NULL; ! 820: ! 821: // see if this looks like a phone number ! 822: if (*host == '#') ! 823: host++; ! 824: for (n = 0; n < Q_strlen(host); n++) ! 825: if (host[n] == '.' || host[n] == ':') ! 826: return NULL; ! 827: ! 828: for (n = 0; n < NUM_COM_PORTS; n++) ! 829: if (TTY_IsEnabled(n) && !serialLine[n].connected) ! 830: if ((ret = _Serial_Connect (host, &serialLine[n]))) ! 831: break; ! 832: return ret; ! 833: } ! 834: ! 835: ! 836: static qsocket_t *_Serial_CheckNewConnections (SerialLine *p) ! 837: { ! 838: int command; ! 839: ! 840: p->client = false; ! 841: if (!TTY_CheckForConnection(p->tty)) ! 842: return NULL; ! 843: ! 844: if (TTY_IsModem(p->tty)) ! 845: { ! 846: if (!p->connecting) ! 847: { ! 848: p->connecting = true; ! 849: p->connect_time = net_time; ! 850: } ! 851: else if ((net_time - p->connect_time) > 15.0) ! 852: { ! 853: p->connecting = false; ! 854: TTY_Disconnect(p->tty); ! 855: return NULL; ! 856: } ! 857: } ! 858: ! 859: p->sock = NET_NewQSocket (); ! 860: p->sock->driver = myDriverLevel; ! 861: if (p->sock == NULL) ! 862: { ! 863: Con_Printf("No sockets available\n"); ! 864: return NULL; ! 865: } ! 866: p->sock->driverdata = p; ! 867: ! 868: SZ_Clear(&net_message); ! 869: if (_Serial_GetMessage(p) != 1) ! 870: { ! 871: NET_FreeQSocket(p->sock); ! 872: return NULL; ! 873: } ! 874: ! 875: MSG_BeginReading (); ! 876: command = MSG_ReadByte(); ! 877: ! 878: if (command == CCREQ_SERVER_INFO) ! 879: { ! 880: if (Q_strcmp(MSG_ReadString(), "QUAKE") != 0) ! 881: return NULL; ! 882: ! 883: if (MSG_ReadByte() != SERIAL_PROTOCOL_VERSION) ! 884: return NULL; ! 885: ! 886: SZ_Clear(&net_message); ! 887: MSG_WriteByte(&net_message, CCREP_SERVER_INFO); ! 888: MSG_WriteString(&net_message, hostname.string); ! 889: MSG_WriteString(&net_message, sv.name); ! 890: MSG_WriteByte(&net_message, net_activeconnections); ! 891: MSG_WriteByte(&net_message, svs.maxclients); ! 892: Serial_SendControlMessage (p, &net_message); ! 893: SZ_Clear(&net_message); ! 894: return NULL; ! 895: } ! 896: ! 897: if (command != CCREQ_CONNECT) ! 898: return NULL; ! 899: ! 900: if (Q_strcmp(MSG_ReadString(), "QUAKE") != 0) ! 901: return NULL; ! 902: ! 903: // send him back the info about the server connection he has been allocated ! 904: SZ_Clear(&net_message); ! 905: MSG_WriteByte(&net_message, CCREP_ACCEPT); ! 906: Serial_SendControlMessage (p, &net_message); ! 907: SZ_Clear(&net_message); ! 908: ! 909: p->connected = true; ! 910: p->connecting = false; ! 911: p->sock->lastMessageTime = net_time; ! 912: sprintf(p->sock->address, "COM%u", (int)((p - serialLine) + 1)); ! 913: ! 914: return p->sock; ! 915: } ! 916: ! 917: qsocket_t *Serial_CheckNewConnections (void) ! 918: { ! 919: int n; ! 920: qsocket_t *ret = NULL; ! 921: ! 922: for (n = 0; n < NUM_COM_PORTS; n++) ! 923: if (TTY_IsEnabled(n) && !serialLine[n].connected) ! 924: if ((ret = _Serial_CheckNewConnections (&serialLine[n]))) ! 925: break; ! 926: return ret; ! 927: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.