1/* 2 File: IrDscInfo.cpp 3 4 Contains: Implementation of IrDscInfo (XID discovery/device info) class 5 6 7*/ 8 9#include "IrDscInfo.h" 10#include "CBufferSegment.h" 11//#include "IrConstData.h" 12 13#define super OSObject 14 OSDefineMetaClassAndStructors(TIrDscInfo, OSObject); 15 16//-------------------------------------------------------------------------------- 17// TIrDscInfo 18//-------------------------------------------------------------------------------- 19TIrDscInfo * 20TIrDscInfo::tIrDscInfo() 21{ 22 TIrDscInfo *obj = new TIrDscInfo; 23 if (obj && !obj->init()) { 24 obj->release(); 25 obj = nil; 26 } 27 return obj; 28} 29 30void 31TIrDscInfo::free() 32{ 33 super::free(); 34} 35 36 37bool 38TIrDscInfo::init() 39{ 40 41 fDevAddr = 0; 42 fHints = 0; 43 fVersion = 0; 44 fCharset = 0; 45 bzero(fNickname, sizeof(fNickname)); 46 bzero(fHintCount, sizeof(fHintCount)); 47 48 if (!super::init()) return false; 49 50 return true; 51} // TIrDscInfo::init 52 53 54//-------------------------------------------------------------------------------- 55// SetServiceHints 56//-------------------------------------------------------------------------------- 57void TIrDscInfo::SetServiceHints( ULong hints ) 58{ 59 fHints |= hints; 60 61 for( int index = 0; index < kHintCount; index++ ) { 62 if( hints & ( 1<<index ) ) 63 fHintCount[index]++; 64 } 65} 66 67 68//-------------------------------------------------------------------------------- 69// RemoveServiceHints 70//-------------------------------------------------------------------------------- 71void TIrDscInfo::RemoveServiceHints( ULong hints ) 72{ 73 for( int index = 0; index < kHintCount; index++ ) { 74 ULong hintMask = 1<<index; 75 if( hints & hintMask ) { 76 fHintCount[index]--; 77 if( fHintCount[index] == 0 ) 78 fHints &= ~hintMask; 79 } 80 } 81} 82 83 84//-------------------------------------------------------------------------------- 85// SetNickname 86//-------------------------------------------------------------------------------- 87IrDAErr TIrDscInfo::SetNickname(const char* name) 88{ 89 ULong nameLen; 90 91 nameLen = strlen(name); 92 if (nameLen > kMaxNicknameLen) { 93 return errBadArg; 94 } 95 96 strlcpy((char*)&fNickname[0], name, sizeof(fNickname)); 97 return noErr; 98 99} // TIrDscInfo::SetNickname 100 101 102//-------------------------------------------------------------------------------- 103// GetNickname 104//-------------------------------------------------------------------------------- 105void TIrDscInfo::GetNickname(UChar* name, int maxnamelen) 106{ 107 // Note: name provided must be at least kMaxNicknameLen chars long 108 // It is responsibility of IrGlue code that uses this to ensure that. 109 strlcpy((char*)name, (const char*)&fNickname[0], maxnamelen); 110 111} // TIrDscInfo::GetNickname 112 113 114//-------------------------------------------------------------------------------- 115// AddDevInfoToBuffer 116//-------------------------------------------------------------------------------- 117ULong TIrDscInfo::AddDevInfoToBuffer(UByte* buffer, ULong maxBytes) 118{ 119#pragma unused(maxBytes) 120 121 UByte hintByte; 122 ULong index; 123 ULong hints; 124 ULong nameLen; 125 ULong devInfoLen = 0; 126 127 // Store the hint byte(s) 128 for (hints = fHints, index = 0; index < 4; index++) { 129 // Mask off next hint byte 130 hintByte = (UByte)(hints & 0xFF); 131 hints >>= 8; 132 133 // If more hint bytes, set the extension bit 134 if (hints != 0) { 135 hintByte |= kDevInfoHintExtension1; 136 } 137 else // jdg: protect us from garbage hints being set 138 hintByte &= ~kDevInfoHintExtension1; // make sure it's off 139 140 // Store the hintByte, inc byte count 141 *buffer++ = hintByte; 142 devInfoLen++; 143 144 // No more hint bytes? 145 if (hints == 0) break; 146 } 147 148 // Add the character set encoding (I'm only supporting ASCII for now) 149 *buffer++ = GetCharacterSet(); 150 devInfoLen++; 151 152 // Figure out how much of the name can be written out 153 nameLen = Min(strlen((const char*)&fNickname[0]), kMaxNicknameLen - (devInfoLen - 2)); 154 memcpy(buffer, fNickname, (unsigned int)nameLen); 155 devInfoLen += nameLen; 156 157 return devInfoLen; 158 159} // TIrDscInfo::AddDevInfoToBuffer 160 161 162//-------------------------------------------------------------------------------- 163// ExtractDevInfoFromBuffer 164//-------------------------------------------------------------------------------- 165IrDAErr TIrDscInfo::ExtractDevInfoFromBuffer(CBufferSegment *buffer) 166{ 167 UByte hintByte; 168 ULong index; 169 ULong bytesRead; 170 UByte devInfo[4 + 1 + kMaxNicknameLen]; 171 172 // Initialize fields (in case no devInfo was provided - which is supposedly okay?) 173 fHints = 0; 174 fNickname[0] = 0; 175 176 // Read in maximum 177 bytesRead = buffer->Getn(&devInfo[0], sizeof(devInfo)); 178 179 // Parse the hint byte(s) 180 for (index = 0; index < bytesRead; ) { 181 hintByte = devInfo[index]; 182 fHints |= (hintByte & ~kDevInfoHintExtension1) << (index * 8); 183 index++; 184 if ((hintByte & kDevInfoHintExtension1) == 0) break; 185 } 186 187 // Parse the char set byte 188 if (index < bytesRead) { 189 SetCharacterSet(devInfo[index++]); 190 } 191 192 // Now extract the device name (and null terminate it) 193 memcpy(fNickname, &devInfo[index], (unsigned int)(bytesRead - index)); 194 fNickname[bytesRead - index] = 0; 195 196 return noErr; 197 198} // TIrDscInfo::ExtractDevInfoFromBuffer 199 200