1/* 2 * Copyright (c) 2008 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28#include "kdp_serial.h" 29 30#define SKDP_START_CHAR 0xFA 31#define SKDP_END_CHAR 0xFB 32#define SKDP_ESC_CHAR 0xFE 33 34static enum {DS_WAITSTART, DS_READING, DS_ESCAPED} dsState; 35static unsigned char dsBuffer[1518]; 36static int dsPos; 37 38void kdp_serialize_packet(unsigned char *packet, unsigned int len, void (*outFunc)(char)) 39{ 40 unsigned int index; 41 outFunc(SKDP_START_CHAR); 42 for (index = 0; index < len; index++) { 43 unsigned char byte = *packet++; 44 //need to escape '\n' because the kernel serial output turns it into a cr/lf 45 if(byte == SKDP_START_CHAR || byte == SKDP_END_CHAR || byte == SKDP_ESC_CHAR || byte == '\n') 46 { 47 outFunc(SKDP_ESC_CHAR); 48 byte = ~byte; 49 } 50 outFunc(byte); 51 } 52 outFunc(SKDP_END_CHAR); 53} 54 55unsigned char *kdp_unserialize_packet(unsigned char byte, unsigned int *len) 56{ 57 switch(dsState) 58 { 59 case DS_WAITSTART: 60 if(byte == SKDP_START_CHAR) 61 { 62// printf("got start char\n"); 63 dsState = DS_READING; 64 dsPos = 0; 65 *len = SERIALIZE_READING; 66 return 0; 67 } 68 *len = SERIALIZE_WAIT_START; 69 break; 70 case DS_READING: 71 if(byte == SKDP_ESC_CHAR) 72 { 73 dsState = DS_ESCAPED; 74 *len = SERIALIZE_READING; 75 return 0; 76 } 77 if(byte == SKDP_START_CHAR) 78 { 79// printf("unexpected start char, resetting\n"); 80 dsPos = 0; 81 *len = SERIALIZE_READING; 82 return 0; 83 } 84 if(byte == SKDP_END_CHAR) 85 { 86 dsState = DS_WAITSTART; 87 *len = dsPos; 88 dsPos = 0; 89 return dsBuffer; 90 } 91 dsBuffer[dsPos++] = byte; 92 break; 93 case DS_ESCAPED: 94// printf("unescaping %02x to %02x\n", byte, ~byte); 95 dsBuffer[dsPos++] = ~byte; 96 dsState = DS_READING; 97 *len = SERIALIZE_READING; 98 break; 99 } 100 if(dsPos == sizeof(dsBuffer)) //too much data...forget this packet 101 { 102 dsState = DS_WAITSTART; 103 dsPos = 0; 104 *len = SERIALIZE_WAIT_START; 105 } 106 107 return 0; 108} 109