source: src/router/nvram/nvram_linux.c @ 10197

Last change on this file since 10197 was 10197, checked in by eko, 5 years ago

auto recovery of nvram + some dual band changes

File size: 7.0 KB
Line 
1/*
2 * NVRAM variable manipulation (Linux user mode half)
3 *
4 * Copyright 2001-2003, Broadcom Corporation
5 * All Rights Reserved.
6 *
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
11 *
12 * $Id: nvram_linux.c,v 1.9 2003/12/03 10:14:06 honor Exp $
13 */
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <unistd.h>
18#include <errno.h>
19#include <error.h>
20#include <string.h>
21#include <sys/ioctl.h>
22#include <sys/types.h>
23#include <sys/stat.h>
24#include <fcntl.h>
25#include <sys/mman.h>
26
27#include <typedefs.h>
28#include <bcmnvram.h>
29#include <nvram_convert.h>
30
31#define PATH_DEV_NVRAM "/dev/nvram"
32
33/* Globals */
34static int nvram_fd = -1;
35static char *nvram_buf = NULL;
36
37int
38nvram_init (void *unused)
39{
40
41
42  if ((nvram_fd = open (PATH_DEV_NVRAM, O_RDWR)) < 0)
43    goto err;
44
45  /* Map kernel string buffer into user space */
46  if ((nvram_buf =
47       mmap (NULL, NVRAM_SPACE, PROT_READ, MAP_SHARED, nvram_fd,
48             0)) == MAP_FAILED)
49    {
50      close (nvram_fd);
51      fprintf (stderr, "nvram_init(): failed\n");
52      nvram_fd = -1;
53      goto err;
54    }
55
56  return 0;
57
58err:
59  perror (PATH_DEV_NVRAM);
60  return errno;
61}
62
63void
64lock (void)
65{
66  FILE *in;
67  int lockwait=0;
68  while ((in = fopen ("/tmp/.nvlock", "rb")) != NULL)
69    {
70      fclose (in);
71      //cprintf ("nvram lock, waiting....\n");
72      lockwait++;
73      if (lockwait==3)
74        unlink("/tmp/.nvlock"); //something crashed, we fix it
75      sleep (1);
76    }
77  in = fopen ("/tmp/.nvlock", "wb");
78  fprintf (in, "lock");
79  fclose (in);
80}
81
82
83void
84unlock (void)
85{
86  unlink ("/tmp/.nvlock");
87}
88
89char *
90nvram_get (const char *name)
91{
92//lock();
93  size_t count = strlen (name) + 1;
94  char tmp[100], *value;
95  unsigned long *off = (unsigned long *) tmp;
96
97  if (nvram_fd < 0)
98    if (nvram_init (NULL))
99      {
100        //unlock();
101        return NULL;
102      }
103  if (count > sizeof (tmp))
104    {
105      if (!(off = malloc (count)))
106        {
107          //unlock();
108          return NULL;
109        }
110    }
111
112  /* Get offset into mmap() space */
113  strcpy ((char *) off, name);
114
115  count = read (nvram_fd, off, count);
116
117  if (count == sizeof (unsigned long))
118    value = &nvram_buf[*off];
119  else
120    value = NULL;
121
122  if (count < 0)
123    perror (PATH_DEV_NVRAM);
124
125  if (off != (unsigned long *) tmp)
126    free (off);
127  //unlock();
128
129//fprintf(stderr,"nvram_get %s = %s\n",name,value!=NULL?value:"");
130//fprintf(stderr,"NVRAM_GET(%s)=%s\n",name,value);
131  return value;
132}
133
134int
135nvram_getall (char *buf, int count)
136{
137//fprintf(stderr,"getall\n");
138//lock();
139  int ret;
140
141  if (nvram_fd < 0)
142    if ((ret = nvram_init (NULL)))
143      {
144        //unlock();
145        return ret;
146      }
147  if (count == 0)
148    {
149      //unlock();
150      return 0;
151    }
152  /* Get all variables */
153  *buf = '\0';
154
155  ret = read (nvram_fd, buf, count);
156
157  if (ret < 0)
158    perror (PATH_DEV_NVRAM);
159  //unlock();
160  return (ret == count) ? 0 : ret;
161}
162
163void nvram_open(void) // dummy
164{
165}
166void nvram_close(void) //dummy
167{
168}
169
170static int
171_nvram_set (const char *name, const char *value)
172{
173  size_t count = strlen (name) + 1;
174  char tmp[100], *buf = tmp;
175  int ret;
176
177  if (nvram_fd < 0)
178    if ((ret = nvram_init (NULL)))
179      return ret;
180
181  /* Wolf add - keep nvram varname to sane len - may prevent corruption */
182  if (strlen (name) > 64)
183    return -ENOMEM;
184
185  /* Unset if value is NULL */
186  if (value)
187    count += strlen (value) + 1;
188
189  if (count > sizeof (tmp))
190    {
191      if (!(buf = malloc (count)))
192        return -ENOMEM;
193    }
194
195  if (value)
196    sprintf (buf, "%s=%s", name, value);
197  else
198    strcpy (buf, name);
199
200  ret = write (nvram_fd, buf, count);
201
202  if (ret < 0)
203    perror (PATH_DEV_NVRAM);
204
205  if (buf != tmp)
206    free (buf);
207
208  return (ret == count) ? 0 : ret;
209}
210
211int
212nvram_set (const char *name, const char *value)
213{
214//fprintf(stderr,"nvram_set %s=%s\n",name,value);
215
216  extern struct nvram_convert nvram_converts[];
217  struct nvram_convert *v;
218  int ret;
219//lock();
220  ret = _nvram_set (name, value);
221
222  for (v = nvram_converts; v->name; v++)
223    {
224      if (!strcmp (v->name, name))
225        {
226          if (strcmp (v->wl0_name, ""))
227            _nvram_set (v->wl0_name, value);
228          if (strcmp (v->d11g_name, ""))
229            _nvram_set (v->d11g_name, value);
230        //Jemmy add for dual band wireless 2008.3.1
231      if (!nvram_match("restore_defaults", "0") || !nvram_match("os_name", "linux"))     
232    {
233          if(strcmp(v->wl1_name,""))
234            _nvram_set(v->wl1_name, value);
235        }
236          if ((!strcmp(v->wl1_name, "wl1_maclist")) || (!strcmp(v->wl1_name, "wl1_macmode")))
237                _nvram_set(v->wl1_name, value);     
238        }
239    }
240//unlock();
241  return ret;
242}
243int nvram_immed_set (const char *name, const char *value)
244{
245return nvram_set(name,value);
246}
247
248
249int
250nvram_unset (const char *name)
251{
252//lock();
253//fprintf(stderr,"nvram_unset %s\n",name);
254  int v = _nvram_set (name, NULL);
255//unlock();
256  return v;
257}
258
259int
260nvram_commit (void)
261{
262system("/sbin/ledtool 1");
263//fprintf(stderr,"nvram_commit \n");
264  lock ();
265  int ret;
266  //fprintf (stderr, "nvram_commit(): start\n");
267  if (nvram_fd < 0)
268    {
269      if ((ret = nvram_init (NULL)))
270        {
271          fprintf (stderr, "nvram_commit(): failed\n");
272          unlock ();
273          return ret;
274        }
275    }
276  ret = ioctl (nvram_fd, NVRAM_MAGIC, NULL);
277
278  if (ret < 0)
279    {
280      fprintf (stderr, "nvram_commit(): failed\n");
281      perror (PATH_DEV_NVRAM);
282    }
283
284  fprintf (stderr, "nvram_commit(): end\n");
285  unlock ();
286  return ret;
287}
288
289int
290file2nvram (char *filename, char *varname)
291{
292  FILE *fp;
293  int c, count;
294  int i = 0, j = 0;
295  char mem[10000], buf[30000];
296
297  if (!(fp = fopen (filename, "rb")))
298    return 0;
299
300  count = fread (mem, 1, sizeof (mem), fp);
301  fclose (fp);
302  for (j = 0; j < count; j++)
303    {
304      if (i > sizeof (buf) - 3)
305        break;
306      c = mem[j];
307      if (c >= 32 && c <= 126 && c != '~')
308        {
309          buf[i++] = (unsigned char) c;
310        }
311      else if (c == 13)
312        {
313          buf[i++] = (unsigned char) c;
314        }
315      else if (c == 0)
316        {
317          buf[i++] = '~';
318        }
319      else if (c == 10)
320        {
321          buf[i++] = (unsigned char) c;
322        }
323      else
324        {
325          buf[i++] = '\\';
326          sprintf (buf + i, "%02X", c);
327          i += 2;
328        }
329    }
330  if (i == 0)
331    return 0;
332  buf[i] = 0;
333  //fprintf(stderr,"================ > file2nvram %s = [%s] \n",varname,buf);
334  nvram_set (varname, buf);
335
336}
337
338int
339nvram2file (char *varname, char *filename)
340{
341  FILE *fp;
342  int c, tmp;
343  int i = 0, j = 0;
344  char *buf;
345  char mem[10000];
346
347  if (!(fp = fopen (filename, "wb")))
348    return 0;
349
350  buf = strdup (nvram_safe_get (varname));
351  //fprintf(stderr,"=================> nvram2file %s = [%s] \n",varname,buf);
352  while (buf[i] && j < sizeof (mem) - 3)
353    {
354/*        if (buf[i] == '\\')  {
355                i++;
356                tmp=buf[i+2];
357                buf[i+2]=0;
358                sscanf(buf+i,"%02X",&c);
359                buf[i+2]=tmp;
360                i+=2;
361                mem[j]=c;j++;
362        } else */
363      if (buf[i] == '~')
364        {
365          mem[j] = 0;
366          j++;
367          i++;
368        }
369      else
370        {
371          mem[j] = buf[i];
372          j++;
373          i++;
374        }
375    }
376  if (j <= 0)
377    return j;
378  j = fwrite (mem, 1, j, fp);
379  fclose (fp);
380  free (buf);
381  return j;
382}
383
384#include "nvram_generics.h"
Note: See TracBrowser for help on using the repository browser.