1/******************************************************************************* 2 * Agere Systems Inc. 3 * Wireless device driver for Linux (wlags49). 4 * 5 * Copyright (c) 1998-2003 Agere Systems Inc. 6 * All rights reserved. 7 * http://www.agere.com 8 * 9 * Initially developed by TriplePoint, Inc. 10 * http://www.triplepoint.com 11 * 12 *------------------------------------------------------------------------------ 13 * 14 * This file defines routines required to parse configuration parameters 15 * listed in a config file, if that config file exists. 16 * 17 *------------------------------------------------------------------------------ 18 * 19 * SOFTWARE LICENSE 20 * 21 * This software is provided subject to the following terms and conditions, 22 * which you should read carefully before using the software. Using this 23 * software indicates your acceptance of these terms and conditions. If you do 24 * not agree with these terms and conditions, do not use the software. 25 * 26 * Copyright � 2003 Agere Systems Inc. 27 * All rights reserved. 28 * 29 * Redistribution and use in source or binary forms, with or without 30 * modifications, are permitted provided that the following conditions are met: 31 * 32 * . Redistributions of source code must retain the above copyright notice, this 33 * list of conditions and the following Disclaimer as comments in the code as 34 * well as in the documentation and/or other materials provided with the 35 * distribution. 36 * 37 * . Redistributions in binary form must reproduce the above copyright notice, 38 * this list of conditions and the following Disclaimer in the documentation 39 * and/or other materials provided with the distribution. 40 * 41 * . Neither the name of Agere Systems Inc. nor the names of the contributors 42 * may be used to endorse or promote products derived from this software 43 * without specific prior written permission. 44 * 45 * Disclaimer 46 * 47 * THIS SOFTWARE IS PROVIDED �AS IS� AND ANY EXPRESS OR IMPLIED WARRANTIES, 48 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF 49 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY 50 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN 51 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY 52 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 53 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 54 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 55 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 57 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 58 * DAMAGE. 59 * 60 ******************************************************************************/ 61 62/* Only include this file if USE_PROFILE is defined */ 63#ifdef USE_PROFILE 64 65 66 67 68/******************************************************************************* 69 * constant definitions 70 ******************************************************************************/ 71 72 73/* Allow support for calling system fcns to parse config file */ 74#define __KERNEL_SYSCALLS__ 75 76 77 78 79/******************************************************************************* 80 * include files 81 ******************************************************************************/ 82#include <wl_version.h> 83 84#include <linux/netdevice.h> 85#include <linux/etherdevice.h> 86#include <linux/unistd.h> 87#include <asm/uaccess.h> 88#include <limits.h> 89 90#define BIN_DL 1 91 92#include <debug.h> 93#include <hcf.h> 94/* #include <hcfdef.h> */ 95 96#include <wl_if.h> 97#include <wl_internal.h> 98#include <wl_util.h> 99#include <wl_enc.h> 100#include <wl_main.h> 101#include <wl_profile.h> 102 103 104/******************************************************************************* 105 * global variables 106 ******************************************************************************/ 107 108/* Definition needed to prevent unresolved external in unistd.h */ 109static int errno; 110 111#if DBG 112extern p_u32 DebugFlag; 113extern dbg_info_t *DbgInfo; 114#endif 115 116int parse_yes_no(char *value); 117 118 119int parse_yes_no(char *value) 120{ 121int rc = 0; /* default to NO for invalid parameters */ 122 123 if (strlen(value) == 1) { 124 if ((value[0] | ('Y'^'y')) == 'y') 125 rc = 1; 126 /* } else { */ 127 /* this should not be debug time info, it is an enduser data entry error ;? */ 128 /* DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MICROWAVE_ROBUSTNESS); */ 129 } 130 return rc; 131} /* parse_yes_no */ 132 133 134/******************************************************************************* 135 * parse_config() 136 ******************************************************************************* 137 * 138 * DESCRIPTION: 139 * 140 * This function opens the device's config file and parses the options from 141 * it, so that it can properly configure itself. If no configuration file 142 * or configuration is present, then continue to use the options already 143 * parsed from config.opts or wireless.opts. 144 * 145 * PARAMETERS: 146 * 147 * dev - a pointer to the device's net_device structure 148 * 149 * RETURNS: 150 * 151 * N/A 152 * 153 ******************************************************************************/ 154void parse_config(struct net_device *dev) 155{ 156 int file_desc; 157 char buffer[MAX_LINE_SIZE]; 158 char filename[MAX_LINE_SIZE]; 159 mm_segment_t fs; 160 struct wl_private *wvlan_config = NULL; 161 ENCSTRCT sEncryption; 162 /*------------------------------------------------------------------------*/ 163 164 DBG_FUNC("parse_config"); 165 DBG_ENTER(DbgInfo); 166 167 /* Get the wavelan specific info for this device */ 168 wvlan_config = dev->priv; 169 if (wvlan_config == NULL) { 170 DBG_ERROR(DbgInfo, "Wavelan specific info struct not present?\n"); 171 return; 172 } 173 174 /* setup the default encryption string */ 175 strcpy(wvlan_config->szEncryption, DEF_CRYPT_STR); 176 177 /* Obtain a user-space process context, storing the original context */ 178 fs = get_fs(); 179 set_fs(get_ds()); 180 181 /* Determine the filename for this device and attempt to open it */ 182 sprintf(filename, "%s%s", ROOT_CONFIG_FILENAME, dev->name); 183 file_desc = open(filename, O_RDONLY, 0); 184 if (file_desc != -1) { 185 DBG_TRACE(DbgInfo, "Wireless config file found. Parsing options...\n"); 186 187 /* Read out the options */ 188 while (readline(file_desc, buffer)) 189 translate_option(buffer, wvlan_config); 190 /* Close the file */ 191 close(file_desc); /* ;?even if file_desc == -1 ??? */ 192 } else { 193 DBG_TRACE(DbgInfo, "No iwconfig file found for this device; " 194 "config.opts or wireless.opts will be used\n"); 195 } 196 /* Return to the original context */ 197 set_fs(fs); 198 199 /* convert the WEP keys, if read in as key1, key2, type of data */ 200 if (wvlan_config->EnableEncryption) { 201 memset(&sEncryption, 0, sizeof(sEncryption)); 202 203 wl_wep_decode(CRYPT_CODE, &sEncryption, 204 wvlan_config->szEncryption); 205 206 /* the Linux driver likes to use 1-4 for the key IDs, and then 207 convert to 0-3 when sending to the card. The Windows code 208 base used 0-3 in the API DLL, which was ported to Linux. For 209 the sake of the user experience, we decided to keep 0-3 as the 210 numbers used in the DLL; and will perform the +1 conversion here. 211 We could have converted the entire Linux driver, but this is 212 less obtrusive. This may be a "todo" to convert the whole driver */ 213 sEncryption.wEnabled = wvlan_config->EnableEncryption; 214 sEncryption.wTxKeyID = wvlan_config->TransmitKeyID - 1; 215 216 memcpy(&sEncryption.EncStr, &wvlan_config->DefaultKeys, 217 sizeof(CFG_DEFAULT_KEYS_STRCT)); 218 219 memset(wvlan_config->szEncryption, 0, sizeof(wvlan_config->szEncryption)); 220 221 wl_wep_code(CRYPT_CODE, wvlan_config->szEncryption, &sEncryption, 222 sizeof(sEncryption)); 223 } 224 225 /* decode the encryption string for the call to wl_commit() */ 226 wl_wep_decode(CRYPT_CODE, &sEncryption, wvlan_config->szEncryption); 227 228 wvlan_config->TransmitKeyID = sEncryption.wTxKeyID + 1; 229 wvlan_config->EnableEncryption = sEncryption.wEnabled; 230 231 memcpy(&wvlan_config->DefaultKeys, &sEncryption.EncStr, 232 sizeof(CFG_DEFAULT_KEYS_STRCT)); 233 234 235 DBG_LEAVE(DbgInfo); 236 return; 237} /* parse_config */ 238 239/******************************************************************************* 240 * readline() 241 ******************************************************************************* 242 * 243 * DESCRIPTION: 244 * 245 * This function reads in data from a given file one line at a time, 246 * converting the detected newline character '\n' to a null '\0'. Note that 247 * the file descriptor must be valid before calling this function. 248 * 249 * PARAMETERS: 250 * 251 * filedesc - the file descriptor for the open configuration file 252 * buffer - a buffer pointer, passed in by the caller, to which the 253 * line will be stored. 254 * 255 * RETURNS: 256 * 257 * the number of bytes read 258 * -1 on error 259 * 260 ******************************************************************************/ 261int readline(int filedesc, char *buffer) 262{ 263 int result = -1; 264 int bytes_read = 0; 265 /*------------------------------------------------------------------------*/ 266 267 /* Make sure the file descriptor is good */ 268 if (filedesc != -1) { 269 /* Read in from the file byte by byte until a newline is reached */ 270 while ((result = read(filedesc, &buffer[bytes_read], 1)) == 1) { 271 if (buffer[bytes_read] == '\n') { 272 buffer[bytes_read] = '\0'; 273 bytes_read++; 274 break; 275 } 276 bytes_read++; 277 } 278 } 279 280 /* Return the number of bytes read */ 281 if (result == -1) 282 return result; 283 else 284 return bytes_read; 285} /* readline */ 286/*============================================================================*/ 287 288/******************************************************************************* 289 * translate_option() 290 ******************************************************************************* 291 * 292 * DESCRIPTION: 293 * 294 * This function takes a line read in from the config file and parses out 295 * the key/value pairs. It then determines which key has been parsed and sets 296 * the card's configuration based on the value given. 297 * 298 * PARAMETERS: 299 * 300 * buffer - a buffer containing a line to translate 301 * config - a pointer to the device's private adapter structure 302 * 303 * RETURNS: 304 * 305 * N/A 306 * 307 ******************************************************************************/ 308void translate_option(char *buffer, struct wl_private *lp) 309{ 310 unsigned int value_convert = 0; 311 int string_length = 0; 312 char *key = NULL; 313 char *value = NULL; 314 u_char mac_value[ETH_ALEN]; 315 /*------------------------------------------------------------------------*/ 316 317 DBG_FUNC("translate_option"); 318 319 if (buffer == NULL || lp == NULL) { 320 DBG_ERROR(DbgInfo, "Config file buffer and/or wavelan buffer ptr NULL\n"); 321 return; 322 } 323 324 ParseConfigLine(buffer, &key, &value); 325 326 if (key == NULL || value == NULL) 327 return; 328 329 /* Determine which key it is and perform the appropriate action */ 330 331 /* Configuration parameters used in all scenarios */ 332#if DBG 333 /* handle DebugFlag as early as possible so it starts its influence as early 334 * as possible 335 */ 336 if (strcmp(key, PARM_NAME_DEBUG_FLAG) == 0) { 337 if (DebugFlag == ~0) { /* if DebugFlag is not specified on the command line */ 338 if (DbgInfo->DebugFlag == 0) { /* if pc_debug did not set DebugFlag (i.e.pc_debug is 339 * not specified or specified outside the 4-8 range 340 */ 341 DbgInfo->DebugFlag |= DBG_DEFAULTS; 342 } 343 } else { 344 DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); /* ;?DebugFlag; */ 345 } 346 DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); /* ;?Delete ASAP */ 347 } 348#endif /* DBG */ 349 if (strcmp(key, PARM_NAME_AUTH_KEY_MGMT_SUITE) == 0) { 350 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_AUTH_KEY_MGMT_SUITE, value); 351 352 value_convert = simple_strtoul(value, NULL, 0); 353 if ((value_convert >= PARM_MIN_AUTH_KEY_MGMT_SUITE) || (value_convert <= PARM_MAX_AUTH_KEY_MGMT_SUITE)) 354 lp->AuthKeyMgmtSuite = value_convert; 355 else 356 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_AUTH_KEY_MGMT_SUITE); 357 } else if (strcmp(key, PARM_NAME_BRSC_2GHZ) == 0) { 358 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_2GHZ, value); 359 360 value_convert = simple_strtoul(value, NULL, 0); 361 if ((value_convert >= PARM_MIN_BRSC) || (value_convert <= PARM_MAX_BRSC)) 362 lp->brsc[0] = value_convert; 363 else 364 DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_BRSC_2GHZ); 365 } else if (strcmp(key, PARM_NAME_BRSC_5GHZ) == 0) { 366 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_5GHZ, value); 367 368 value_convert = simple_strtoul(value, NULL, 0); 369 if ((value_convert >= PARM_MIN_BRSC) || (value_convert <= PARM_MAX_BRSC)) 370 lp->brsc[1] = value_convert; 371 else 372 DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_BRSC_5GHZ); 373 } else if ((strcmp(key, PARM_NAME_DESIRED_SSID) == 0) || (strcmp(key, PARM_NAME_OWN_SSID) == 0)) { 374 DBG_TRACE(DbgInfo, "SSID, value: %s\n", value); 375 376 memset(lp->NetworkName, 0, (PARM_MAX_NAME_LEN + 1)); 377 378 /* Make sure the value isn't too long */ 379 string_length = strlen(value); 380 if (string_length > PARM_MAX_NAME_LEN) { 381 DBG_WARNING(DbgInfo, "SSID too long; will be truncated\n"); 382 string_length = PARM_MAX_NAME_LEN; 383 } 384 385 memcpy(lp->NetworkName, value, string_length); 386 } 387 else if (strcmp(key, PARM_NAME_ENABLE_ENCRYPTION) == 0) { 388 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_ENABLE_ENCRYPTION, value); 389 390 value_convert = simple_strtoul(value, NULL, 0); 391 if ((value_convert >= PARM_MIN_ENABLE_ENCRYPTION) && (value_convert <= PARM_MAX_ENABLE_ENCRYPTION)) 392 lp->EnableEncryption = value_convert; 393 else 394 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_ENABLE_ENCRYPTION); 395 } else if (strcmp(key, PARM_NAME_ENCRYPTION) == 0) { 396 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_ENCRYPTION, value); 397 398 memset(lp->szEncryption, 0, sizeof(lp->szEncryption)); 399 400 /* Make sure the value isn't too long */ 401 string_length = strlen(value); 402 if (string_length > sizeof(lp->szEncryption)) { 403 DBG_WARNING(DbgInfo, "%s too long; will be truncated\n", PARM_NAME_ENCRYPTION); 404 string_length = sizeof(lp->szEncryption); 405 } 406 407 memcpy(lp->szEncryption, value, string_length); 408 } else if (strcmp(key, PARM_NAME_KEY1) == 0) { 409 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_KEY1, value); 410 411 if (is_valid_key_string(value)) { 412 memset(lp->DefaultKeys.key[0].key, 0, MAX_KEY_SIZE); 413 414 key_string2key(value, &lp->DefaultKeys.key[0]); 415 } else { 416 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY1); 417 } 418 } else if (strcmp(key, PARM_NAME_KEY2) == 0) { 419 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_KEY2, value); 420 421 if (is_valid_key_string(value)) { 422 memset(lp->DefaultKeys.key[1].key, 0, MAX_KEY_SIZE); 423 424 key_string2key(value, &lp->DefaultKeys.key[1]); 425 } else { 426 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY2); 427 } 428 } else if (strcmp(key, PARM_NAME_KEY3) == 0) { 429 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_KEY3, value); 430 431 if (is_valid_key_string(value)) { 432 memset(lp->DefaultKeys.key[2].key, 0, MAX_KEY_SIZE); 433 434 key_string2key(value, &lp->DefaultKeys.key[2]); 435 } else { 436 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY3); 437 } 438 } else if (strcmp(key, PARM_NAME_KEY4) == 0) { 439 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_KEY4, value); 440 441 if (is_valid_key_string(value)) { 442 memset(lp->DefaultKeys.key[3].key, 0, MAX_KEY_SIZE); 443 444 key_string2key(value, &lp->DefaultKeys.key[3]); 445 } else { 446 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY4); 447 } 448 } 449 /* New Parameters for WARP */ 450 else if (strcmp(key, PARM_NAME_LOAD_BALANCING) == 0) { 451 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_LOAD_BALANCING, value); 452 lp->loadBalancing = parse_yes_no(value); 453 } else if (strcmp(key, PARM_NAME_MEDIUM_DISTRIBUTION) == 0) { 454 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MEDIUM_DISTRIBUTION, value); 455 lp->mediumDistribution = parse_yes_no(value); 456 } else if (strcmp(key, PARM_NAME_MICROWAVE_ROBUSTNESS) == 0) { 457 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MICROWAVE_ROBUSTNESS, value); 458 lp->MicrowaveRobustness = parse_yes_no(value); 459 } else if (strcmp(key, PARM_NAME_MULTICAST_RATE) == 0) { 460 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_RATE, value); 461 462 value_convert = simple_strtoul(value, NULL, 0); 463 464 if ((value_convert >= PARM_MIN_MULTICAST_RATE) && (value_convert <= PARM_MAX_MULTICAST_RATE)) 465 lp->MulticastRate[0] = value_convert; 466 else 467 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MULTICAST_RATE); 468 } else if (strcmp(key, PARM_NAME_OWN_CHANNEL) == 0) { 469 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_CHANNEL, value); 470 471 value_convert = simple_strtoul(value, NULL, 0); 472 if (wl_is_a_valid_chan(value_convert)) { 473 if (value_convert > 14) 474 value_convert = value_convert | 0x100; 475 lp->Channel = value_convert; 476 } else { 477 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_CHANNEL); 478 } 479 } else if (strcmp(key, PARM_NAME_OWN_NAME) == 0) { 480 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_NAME, value); 481 482 memset(lp->StationName, 0, (PARM_MAX_NAME_LEN + 1)); 483 484 /* Make sure the value isn't too long */ 485 string_length = strlen(value); 486 if (string_length > PARM_MAX_NAME_LEN) { 487 DBG_WARNING(DbgInfo, "%s too long; will be truncated\n", PARM_NAME_OWN_NAME); 488 string_length = PARM_MAX_NAME_LEN; 489 } 490 491 memcpy(lp->StationName, value, string_length); 492 } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD) == 0) { 493 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD, value); 494 495 value_convert = simple_strtoul(value, NULL, 0); 496 if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) 497 lp->RTSThreshold = value_convert; 498 else 499 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD); 500 } else if (strcmp(key, PARM_NAME_SRSC_2GHZ) == 0) { 501 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_2GHZ, value); 502 503 value_convert = simple_strtoul(value, NULL, 0); 504 if ((value_convert >= PARM_MIN_SRSC) || (value_convert <= PARM_MAX_SRSC)) 505 lp->srsc[0] = value_convert; 506 else 507 DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_SRSC_2GHZ); 508 } else if (strcmp(key, PARM_NAME_SRSC_5GHZ) == 0) { 509 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_5GHZ, value); 510 511 value_convert = simple_strtoul(value, NULL, 0); 512 if ((value_convert >= PARM_MIN_SRSC) || (value_convert <= PARM_MAX_SRSC)) 513 lp->srsc[1] = value_convert; 514 else 515 DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_SRSC_5GHZ); 516 } else if (strcmp(key, PARM_NAME_SYSTEM_SCALE) == 0) { 517 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SYSTEM_SCALE, value); 518 519 value_convert = simple_strtoul(value, NULL, 0); 520 if ((value_convert >= PARM_MIN_SYSTEM_SCALE) && (value_convert <= PARM_MAX_SYSTEM_SCALE)) 521 lp->DistanceBetweenAPs = value_convert; 522 else 523 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_SYSTEM_SCALE); 524 } else if (strcmp(key, PARM_NAME_TX_KEY) == 0) { 525 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_KEY, value); 526 527 value_convert = simple_strtoul(value, NULL, 0); 528 if ((value_convert >= PARM_MIN_TX_KEY) && (value_convert <= PARM_MAX_TX_KEY)) 529 lp->TransmitKeyID = simple_strtoul(value, NULL, 0); 530 else 531 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_KEY); 532 } else if (strcmp(key, PARM_NAME_TX_RATE) == 0) { 533 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE, value); 534 535 value_convert = simple_strtoul(value, NULL, 0); 536 if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) 537 lp->TxRateControl[0] = value_convert; 538 else 539 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE); 540 } else if (strcmp(key, PARM_NAME_TX_POW_LEVEL) == 0) { 541 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_POW_LEVEL, value); 542 543 value_convert = simple_strtoul(value, NULL, 0); 544 if ((value_convert >= PARM_MIN_TX_POW_LEVEL) || (value_convert <= PARM_MAX_TX_POW_LEVEL)) 545 lp->txPowLevel = value_convert; 546 else 547 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_POW_LEVEL); 548 } 549 550 /* Need to add? : Country code, Short/Long retry */ 551 552 /* Configuration parameters specific to STA mode */ 553/* ;?seems reasonable that even an AP-only driver could afford this small additional footprint */ 554 if (CNV_INT_TO_LITTLE(lp->hcfCtx.IFB_FWIdentity.comp_id) == COMP_ID_FW_STA) { 555 /* ;?should we return an error status in AP mode */ 556 if (strcmp(key, PARM_NAME_PORT_TYPE) == 0) { 557 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PORT_TYPE, value); 558 559 value_convert = simple_strtoul(value, NULL, 0); 560 if ((value_convert == PARM_MIN_PORT_TYPE) || (value_convert == PARM_MAX_PORT_TYPE)) 561 lp->PortType = value_convert; 562 else 563 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PORT_TYPE); 564 } else if (strcmp(key, PARM_NAME_PM_ENABLED) == 0) { 565 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PM_ENABLED, value); 566 value_convert = simple_strtoul(value, NULL, 0); 567 /* ;? how about wl_main.c containing 568 * VALID_PARAM(PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD || 569 * (PARM_PM_ENABLED & 0x7FFF) <= WVLAN_PM_STATE_STANDARD); 570 */ 571 if ((value_convert & 0x7FFF) <= PARM_MAX_PM_ENABLED) { 572 lp->PMEnabled = value_convert; 573 } else { 574 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PM_ENABLED); 575 /* ;?this is a data entry error, hence not a DBG_WARNING */ 576 } 577 } else if (strcmp(key, PARM_NAME_CREATE_IBSS) == 0) { 578 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_CREATE_IBSS, value); 579 lp->CreateIBSS = parse_yes_no(value); 580 } else if (strcmp(key, PARM_NAME_MULTICAST_RX) == 0) { 581 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_RX, value); 582 lp->MulticastReceive = parse_yes_no(value); 583 } else if (strcmp(key, PARM_NAME_MAX_SLEEP) == 0) { 584 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MAX_SLEEP, value); 585 586 value_convert = simple_strtoul(value, NULL, 0); 587 if ((value_convert >= 0) && (value_convert <= 65535)) 588 lp->MaxSleepDuration = value_convert; 589 else 590 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MAX_SLEEP); 591 } else if (strcmp(key, PARM_NAME_NETWORK_ADDR) == 0) { 592 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_NETWORK_ADDR, value); 593 594 if (parse_mac_address(value, mac_value) == ETH_ALEN) 595 memcpy(lp->MACAddress, mac_value, ETH_ALEN); 596 else 597 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_NETWORK_ADDR); 598 } else if (strcmp(key, PARM_NAME_AUTHENTICATION) == 0) { 599 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_AUTHENTICATION, value); 600 601 value_convert = simple_strtoul(value, NULL, 0); 602 if ((value_convert >= PARM_MIN_AUTHENTICATION) && (value_convert <= PARM_MAX_AUTHENTICATION)) 603 lp->authentication = value_convert; 604 else 605 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_AUTHENTICATION); 606 } else if (strcmp(key, PARM_NAME_OWN_ATIM_WINDOW) == 0) { 607 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_ATIM_WINDOW, value); 608 609 value_convert = simple_strtoul(value, NULL, 0); 610 if ((value_convert >= PARM_MIN_OWN_ATIM_WINDOW) && (value_convert <= PARM_MAX_OWN_ATIM_WINDOW)) 611 lp->atimWindow = value_convert; 612 else 613 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_ATIM_WINDOW); 614 } else if (strcmp(key, PARM_NAME_PM_HOLDOVER_DURATION) == 0) { 615 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PM_HOLDOVER_DURATION, value); 616 617 value_convert = simple_strtoul(value, NULL, 0); 618 if ((value_convert >= PARM_MIN_PM_HOLDOVER_DURATION) && (value_convert <= PARM_MAX_PM_HOLDOVER_DURATION)) 619 lp->holdoverDuration = value_convert; 620 else 621 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PM_HOLDOVER_DURATION); 622 } else if (strcmp(key, PARM_NAME_PROMISCUOUS_MODE) == 0) { 623 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PROMISCUOUS_MODE, value); 624 lp->promiscuousMode = parse_yes_no(value); 625 } else if (strcmp(key, PARM_NAME_CONNECTION_CONTROL) == 0) { 626 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_CONNECTION_CONTROL, value); 627 628 value_convert = simple_strtoul(value, NULL, 0); 629 if ((value_convert >= PARM_MIN_CONNECTION_CONTROL) && (value_convert <= PARM_MAX_CONNECTION_CONTROL)) 630 lp->connectionControl = value_convert; 631 else 632 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_CONNECTION_CONTROL); 633 } 634 635 /* Need to add? : Probe Data Rate */ 636 } 637 638 /* Configuration parameters specific to AP mode */ 639 /* ;?should we restore this to allow smaller memory footprint */ 640 if (CNV_INT_TO_LITTLE(lp->hcfCtx.IFB_FWIdentity.comp_id) == COMP_ID_FW_AP) { 641 if (strcmp(key, PARM_NAME_OWN_DTIM_PERIOD) == 0) { 642 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_DTIM_PERIOD, value); 643 644 value_convert = simple_strtoul(value, NULL, 0); 645 if (value_convert >= PARM_MIN_OWN_DTIM_PERIOD) 646 lp->DTIMPeriod = value_convert; 647 else 648 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_DTIM_PERIOD); 649 } else if (strcmp(key, PARM_NAME_REJECT_ANY) == 0) { 650 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_REJECT_ANY, value); 651 lp->RejectAny = parse_yes_no(value); 652 } else if (strcmp(key, PARM_NAME_EXCLUDE_UNENCRYPTED) == 0) { 653 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_EXCLUDE_UNENCRYPTED, value); 654 lp->ExcludeUnencrypted = parse_yes_no(value); 655 } else if (strcmp(key, PARM_NAME_MULTICAST_PM_BUFFERING) == 0) { 656 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_PM_BUFFERING, value); 657 lp->ExcludeUnencrypted = parse_yes_no(value); 658 } else if (strcmp(key, PARM_NAME_INTRA_BSS_RELAY) == 0) { 659 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_INTRA_BSS_RELAY, value); 660 lp->ExcludeUnencrypted = parse_yes_no(value); 661 } else if (strcmp(key, PARM_NAME_OWN_BEACON_INTERVAL) == 0) { 662 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_BEACON_INTERVAL, value); 663 664 value_convert = simple_strtoul(value, NULL, 0); 665 if (value_convert >= PARM_MIN_OWN_BEACON_INTERVAL) 666 lp->ownBeaconInterval = value_convert; 667 else 668 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_BEACON_INTERVAL); 669 } else if (strcmp(key, PARM_NAME_COEXISTENCE) == 0) { 670 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_COEXISTENCE, value); 671 672 value_convert = simple_strtoul(value, NULL, 0); 673 if (value_convert >= PARM_MIN_COEXISTENCE) 674 lp->coexistence = value_convert; 675 else 676 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_COEXISTENCE); 677 } 678 679#ifdef USE_WDS 680 else if (strcmp(key, PARM_NAME_RTS_THRESHOLD1) == 0) { 681 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD1, value); 682 683 value_convert = simple_strtoul(value, NULL, 0); 684 if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) 685 lp->wds_port[0].rtsThreshold = value_convert; 686 else 687 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD1); 688 } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD2) == 0) { 689 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD2, value); 690 691 value_convert = simple_strtoul(value, NULL, 0); 692 if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) 693 lp->wds_port[1].rtsThreshold = value_convert; 694 else 695 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD2); 696 } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD3) == 0) { 697 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD3, value); 698 699 value_convert = simple_strtoul(value, NULL, 0); 700 if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) 701 lp->wds_port[2].rtsThreshold = value_convert; 702 else 703 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD3); 704 } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD4) == 0) { 705 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD4, value); 706 707 value_convert = simple_strtoul(value, NULL, 0); 708 if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) 709 lp->wds_port[3].rtsThreshold = value_convert; 710 else 711 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD4); 712 } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD5) == 0) { 713 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD5, value); 714 715 value_convert = simple_strtoul(value, NULL, 0); 716 if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) 717 lp->wds_port[4].rtsThreshold = value_convert; 718 else 719 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD5); 720 } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD6) == 0) { 721 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD6, value); 722 723 value_convert = simple_strtoul(value, NULL, 0); 724 if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) 725 lp->wds_port[5].rtsThreshold = value_convert; 726 else 727 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD6); 728 } else if (strcmp(key, PARM_NAME_TX_RATE1) == 0) { 729 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE1, value); 730 731 value_convert = simple_strtoul(value, NULL, 0); 732 if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) 733 lp->wds_port[0].txRateCntl = value_convert; 734 else 735 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE1); 736 } else if (strcmp(key, PARM_NAME_TX_RATE2) == 0) { 737 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE2, value); 738 739 value_convert = simple_strtoul(value, NULL, 0); 740 if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) 741 lp->wds_port[1].txRateCntl = value_convert; 742 else 743 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE2); 744 } else if (strcmp(key, PARM_NAME_TX_RATE3) == 0) { 745 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE3, value); 746 747 value_convert = simple_strtoul(value, NULL, 0); 748 if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) 749 lp->wds_port[2].txRateCntl = value_convert; 750 else 751 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE3); 752 } else if (strcmp(key, PARM_NAME_TX_RATE4) == 0) { 753 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE4, value); 754 755 value_convert = simple_strtoul(value, NULL, 0); 756 if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) 757 lp->wds_port[3].txRateCntl = value_convert; 758 else 759 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE4); 760 } else if (strcmp(key, PARM_NAME_TX_RATE5) == 0) { 761 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE5, value); 762 763 value_convert = simple_strtoul(value, NULL, 0); 764 if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) 765 lp->wds_port[4].txRateCntl = value_convert; 766 else 767 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE5); 768 } else if (strcmp(key, PARM_NAME_TX_RATE6) == 0) { 769 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE6, value); 770 771 value_convert = simple_strtoul(value, NULL, 0); 772 if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) 773 lp->wds_port[5].txRateCntl = value_convert; 774 else 775 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE6); 776 } else if (strcmp(key, PARM_NAME_WDS_ADDRESS1) == 0) { 777 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS1, value); 778 779 if (parse_mac_address(value, mac_value) == ETH_ALEN) 780 memcpy(lp->wds_port[0].wdsAddress, mac_value, ETH_ALEN); 781 else 782 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS1); 783 } else if (strcmp(key, PARM_NAME_WDS_ADDRESS2) == 0) { 784 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS2, value); 785 786 if (parse_mac_address(value, mac_value) == ETH_ALEN) 787 memcpy(lp->wds_port[1].wdsAddress, mac_value, ETH_ALEN); 788 else 789 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS2); 790 } else if (strcmp(key, PARM_NAME_WDS_ADDRESS3) == 0) { 791 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS3, value); 792 793 if (parse_mac_address(value, mac_value) == ETH_ALEN) 794 memcpy(lp->wds_port[2].wdsAddress, mac_value, ETH_ALEN); 795 else 796 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS3); 797 } else if (strcmp(key, PARM_NAME_WDS_ADDRESS4) == 0) { 798 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS4, value); 799 800 if (parse_mac_address(value, mac_value) == ETH_ALEN) 801 memcpy(lp->wds_port[3].wdsAddress, mac_value, ETH_ALEN); 802 else 803 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS4); 804 } else if (strcmp(key, PARM_NAME_WDS_ADDRESS5) == 0) { 805 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS5, value); 806 807 if (parse_mac_address(value, mac_value) == ETH_ALEN) 808 memcpy(lp->wds_port[4].wdsAddress, mac_value, ETH_ALEN); 809 else 810 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS5); 811 } else if (strcmp(key, PARM_NAME_WDS_ADDRESS6) == 0) { 812 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS6, value); 813 814 if (parse_mac_address(value, mac_value) == ETH_ALEN) 815 memcpy(lp->wds_port[5].wdsAddress, mac_value, ETH_ALEN); 816 else 817 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS6); 818 } 819#endif /* USE_WDS */ 820 } 821 822 return; 823} /* translate_option */ 824/*============================================================================*/ 825 826/******************************************************************************* 827 * parse_mac_address() 828 ******************************************************************************* 829 * 830 * DESCRIPTION: 831 * 832 * This function will parse a mac address string and convert it to a byte 833 * array. 834 * 835 * PARAMETERS: 836 * 837 * value - the MAC address, represented as a string 838 * byte_array - the MAC address, represented as a byte array of length 839 * ETH_ALEN 840 * 841 * RETURNS: 842 * 843 * The number of bytes in the final MAC address, should equal to ETH_ALEN. 844 * 845 ******************************************************************************/ 846int parse_mac_address(char *value, u_char *byte_array) 847{ 848 int value_offset = 0; 849 int array_offset = 0; 850 int field_offset = 0; 851 char byte_field[3]; 852 /*------------------------------------------------------------------------*/ 853 854 memset(byte_field, '\0', 3); 855 856 while (value[value_offset] != '\0') { 857 /* Skip over the colon chars seperating the bytes, if they exist */ 858 if (value[value_offset] == ':') { 859 value_offset++; 860 continue; 861 } 862 863 byte_field[field_offset] = value[value_offset]; 864 field_offset++; 865 value_offset++; 866 867 /* Once the byte_field is filled, convert it and store it */ 868 if (field_offset == 2) { 869 byte_field[field_offset] = '\0'; 870 byte_array[array_offset] = simple_strtoul(byte_field, NULL, 16); 871 field_offset = 0; 872 array_offset++; 873 } 874 } 875 876 /* Use the array_offset as a check; 6 bytes should be written to the 877 byte_array */ 878 return array_offset; 879} /* parse_mac_address */ 880/*============================================================================*/ 881 882/******************************************************************************* 883 * ParseConfigLine() 884 ******************************************************************************* 885 * 886 * DESCRIPTION: 887 * 888 * Parses a line from the configuration file into an L-val and an R-val, 889 * representing a key/value pair. 890 * 891 * PARAMETERS: 892 * 893 * pszLine - the line from the config file to parse 894 * ppszLVal - the resulting L-val (Key) 895 * ppszRVal - the resulting R-val (Value) 896 * 897 * RETURNS: 898 * 899 * N/A 900 * 901 ******************************************************************************/ 902void ParseConfigLine(char *pszLine, char **ppszLVal, char **ppszRVal) 903{ 904 int i; 905 int size; 906 /*------------------------------------------------------------------------*/ 907 908 DBG_FUNC("ParseConfigLine"); 909 DBG_ENTER(DbgInfo); 910 911 /* get a snapshot of our string size */ 912 size = strlen(pszLine); 913 *ppszLVal = NULL; 914 *ppszRVal = NULL; 915 916 if (pszLine[0] != '#' && /* skip the line if it is a comment */ 917 pszLine[0] != '\n' && /* if it's an empty UNIX line, do nothing */ 918 !(pszLine[0] == '\r' && pszLine[1] == '\n') /* if it's an empty MS-DOS line, do nothing */ 919 ) { 920 /* advance past any whitespace, and assign the L-value */ 921 for (i = 0; i < size; i++) { 922 if (pszLine[i] != ' ') { 923 *ppszLVal = &pszLine[i]; 924 break; 925 } 926 } 927 /* advance to the end of the l-value*/ 928 for (i++; i < size; i++) { 929 if (pszLine[i] == ' ' || pszLine[i] == '=') { 930 pszLine[i] = '\0'; 931 break; 932 } 933 } 934 /* make any whitespace and the equal sign a NULL character, and 935 advance to the R-Value */ 936 for (i++; i < size; i++) { 937 if (pszLine[i] == ' ' || pszLine[i] == '=') { 938 pszLine[i] = '\0'; 939 continue; 940 } 941 *ppszRVal = &pszLine[i]; 942 break; 943 } 944 /* make the line ending character(s) a NULL */ 945 for (i++; i < size; i++) { 946 if (pszLine[i] == '\n') 947 pszLine[i] = '\0'; 948 if ((pszLine[i] == '\r') && (pszLine[i+1] == '\n')) 949 pszLine[i] = '\0'; 950 } 951 } 952 DBG_LEAVE(DbgInfo); 953} /* ParseConfigLine */ 954/*============================================================================*/ 955 956#endif /* USE_PROFILE */ 957