voip-proc.c
上传用户:weyjxb
上传日期:2020-05-18
资源大小:52k
文件大小:9k
源码类别:

多显示器编程

开发平台:

Unix_Linux

  1. /*
  2.  * voipb-proc.c
  3.  * (C) Copyright 2001 by Thomas Davis <tdavis@beeble.homelinux.net>
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify it
  6.  * under the terms of the GNU General Public License as published by the
  7.  * Free Software Foundation; either version 2 of the License, or (at your
  8.  * option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful, but
  11.  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  12.  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13.  * for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software Foundation,
  17.  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  */
  20. #include <linux/init.h>
  21. #include <linux/errno.h>
  22. #include <linux/sched.h>
  23. #include <linux/proc_fs.h>
  24. #include <linux/usb.h>
  25. #include "telephony.h"
  26. #include "voip-ver.h"
  27. #include "voip-config.h"
  28. #include "phonedev.h"
  29. #include "ixjuser.h"
  30. #include "voipblaster.h"
  31. extern int VOIPdebug;
  32. extern char VOIPversion[];
  33. extern void add_caps(struct usb_voipblaster *);
  34. extern struct usb_voipblaster *voipblaster_table[];
  35. static struct proc_dir_entry *voipblaster_proc_entry;
  36. /* Use our own dbg macro */
  37. #undef dbg
  38. #define dbg(format, arg...) do { if (VOIPdebug) printk(KERN_DEBUG __FUNCTION__ ": " format "n" , ## arg); } while (0)
  39. #undef info
  40. #define info(format, arg...) printk(KERN_INFO __FUNCTION__ ": " format "n" , ## arg)
  41. struct setup_entries {
  42. char *name;
  43. int (*get_info)(char *, struct usb_voipblaster *);
  44. struct usb_voipblaster *dev;
  45. };
  46. struct device_entries {
  47. unsigned char serial[10];
  48. int minor;
  49. int status;
  50. };
  51. static struct device_entries devices[VOIP_MAX];
  52. /*
  53.  *
  54.  */
  55. static ssize_t read_debug(struct file *file, char *buf,
  56.   size_t count, loff_t *ppos)
  57. {
  58. unsigned long p = *ppos;
  59. int len;
  60. char debug[6];
  61. dbg("VOIPdebug = %d, count = %d", VOIPdebug, count);
  62. if (count > 6)
  63. count = 6;
  64. len = snprintf(debug, 6, "%dn", VOIPdebug);
  65. if (p >= len)
  66. return 0;
  67. copy_to_user(buf,(void *)debug, len);
  68. *ppos += len;
  69. dbg("len = %d", len);
  70. return len;
  71. }
  72. /*
  73.  * Writing to /proc/voipblaster/debug sets the debug level.
  74.  *
  75.  */
  76. static ssize_t write_debug(struct file * file, const char * buf,
  77.    size_t count, loff_t *ppos)
  78. {
  79. char mybuff[33];
  80. if (count > 32) 
  81. count = 32;
  82. if (copy_from_user(mybuff, buf, count))
  83. return -EFAULT;
  84. mybuff[count-1] = 0;
  85. sscanf(mybuff, "%d", &VOIPdebug);
  86. dbg("count = %d, what = %s, VOIPdebug = %d", count, mybuff, VOIPdebug);
  87. return count;
  88. }
  89. static struct file_operations proc_debug_operations = {
  90. read: read_debug,
  91. write: write_debug,
  92. };
  93. /*
  94.  *
  95.  */
  96. static ssize_t read_devices(struct file *file, char *buf,
  97.     size_t count, loff_t *ppos)
  98. {
  99. unsigned long p = *ppos;
  100. int len;
  101. char debug[6];
  102. dbg("VOIPdebug = %d, count = %d", VOIPdebug, count);
  103. len = sprintf(debug, "devicesn");
  104. if (p >= len)
  105. return 0;
  106. copy_to_user(buf,(void *)debug, len);
  107. *ppos += len;
  108. dbg("len = %d", len);
  109. return len;
  110. }
  111. /*
  112.  * Writing to /proc/voipblaster/debug sets the debug level.
  113.  *
  114.  */
  115. static ssize_t write_devices(struct file * file, const char * buf,
  116.      size_t count, loff_t *ppos)
  117. {
  118. char mybuff[33];
  119. if (count > 32) 
  120. count = 32;
  121. if (copy_from_user(mybuff, buf, count))
  122. return -EFAULT;
  123. #if 0
  124. mybuff[count-1] = 0;
  125. sscanf(mybuff, "%d", &VOIPdebug);
  126. #endif
  127. dbg("count = %d, what = %s, VOIPdebug = %d", count, mybuff, VOIPdebug);
  128. return count;
  129. }
  130. static struct file_operations proc_devices_operations = {
  131. read: read_devices,
  132. write: write_devices,
  133. };
  134. static int api(char *page, struct usb_voipblaster *dev)
  135. {
  136. return sprintf(page, "OLDn");
  137. }
  138. static int revision(char *page, struct usb_voipblaster *dev)
  139. {
  140. return sprintf(page, "%sn", dev->revision);
  141. }
  142. static int version(char *page, struct usb_voipblaster *dev)
  143. {
  144. dbg("version = %s", VOIPversion);
  145. return sprintf(page,"%sn", VOIPversion);
  146. }
  147. static int type(char *page, struct usb_voipblaster *dev)
  148. {
  149. return sprintf(page,"%sn", "Creative USB VOIPBlaster");
  150. }
  151. static int hookstate(char *page, struct usb_voipblaster *dev)
  152. {
  153. return sprintf(page, "%s-hookn", dev->hookstate ? "off" : "on");
  154. }
  155. static int voipminor(char *page, struct usb_voipblaster *dev)
  156. {
  157. return sprintf(page, "%dn", dev->minor);
  158. }
  159. static int status(char *page, struct usb_voipblaster *dev)
  160. {
  161. int len;
  162. len = sprintf(page, "Readers: %dn", dev->readers);
  163. len += sprintf(page + len, "Writers: %dn", dev->writers);
  164. len += sprintf(page + len, "open_count: %dn", dev->open_count);
  165.         return len;
  166. }
  167. static int caps(char *page, struct usb_voipblaster *dev)
  168. {
  169. int len;
  170. add_caps(dev);
  171. len = sprintf(page, "Capabilities: %dn", dev->caps);
  172. len += sprintf(page + len, "PlayCODEC: ");
  173. switch (dev->play_codec) {
  174. case G723_63:
  175. len += sprintf(page + len, "G.723.1_6.3");
  176. break;
  177. case G723_53:
  178. len += sprintf(page + len, "G.723.1_5.3");
  179. break;
  180. default:
  181. len += sprintf(page + len, "NO_CODEC_CHOSEN");
  182. break;
  183. }
  184. len += sprintf(page + len, "nRecordCODEC: ");
  185. switch (dev->rec_codec) {
  186. case G723_63:
  187. len += sprintf(page + len, "G.723.1_6.3");
  188. break;
  189. case G723_53:
  190. len += sprintf(page + len, "G.723.1_5.3");
  191. break;
  192. default:
  193. len += sprintf(page + len, "NO_CODEC_CHOSEN");
  194. break;
  195. }
  196. len += sprintf(page + len, "nAEC: ");
  197. switch (dev->aec_level) {
  198. case AEC_OFF:
  199. len += sprintf(page + len, "Off");
  200. break;
  201. case AEC_LOW:
  202. len += sprintf(page + len, "Low");
  203. break;
  204. case AEC_MED:
  205. len += sprintf(page + len, "Med");
  206. break;
  207. case AEC_HIGH:
  208. len += sprintf(page + len, "High");
  209. break;
  210. case AEC_AUTO:
  211. len += sprintf(page + len, "Auto");
  212. break;
  213. case AEC_AGC:
  214. len += sprintf(page + len, "AEC/AGC");
  215. break;
  216. default:
  217. len += sprintf(page + len, "unknown(%i)", dev->aec_level);
  218. break;
  219. }
  220.         return len;
  221. }
  222. static int portinfo(char *page, struct usb_voipblaster *dev)
  223. {
  224. int len = 0;
  225. switch (dev->port) {
  226. case PORT_POTS:
  227. len += sprintf(page, "POTSn");
  228. break;
  229. case PORT_PSTN:
  230. len += sprintf(page, "PSTNn");
  231. break;
  232. case PORT_SPEAKER:
  233. len += sprintf(page, "SPEAKER/MICn");
  234. break;
  235. case PORT_HANDSET:
  236. len += sprintf(page, "HANDSETn");
  237. break;
  238. default:
  239. len += sprintf(page, "UNKNOWNn");
  240. break;
  241. }
  242.         return len;
  243. }
  244. static int read_proc(char *page, char **start, off_t off,
  245.  int count, int *eof, void *data)
  246. {
  247. int len;
  248. struct setup_entries *p = (struct setup_entries *) data;
  249. struct usb_voipblaster *dev = p->dev;
  250. dbg("calling %s", p->name);
  251. len = p->get_info(page, dev);
  252. if (len <= off+count) 
  253. *eof = 1;
  254.         *start = page + off;
  255.         len -= off;
  256.         if (len>count) 
  257. len = count;
  258.         if (len<0) 
  259. len = 0;
  260. dbg("len = %d", len);
  261.         return len;
  262. }
  263. static struct setup_entries *p, simple_ones[] = {
  264. {"version", &version},
  265. {"api", &api},
  266. {NULL,NULL, NULL},
  267. }, device_files[]= {
  268. {"revision", &revision},
  269. {"status", &status},
  270. {"type", &type },
  271. {"capabilities", &caps},
  272. {"hookstate", &hookstate},
  273. {"port", &portinfo},
  274. {"minor", &voipminor},
  275. {NULL, NULL, NULL},
  276. };
  277. void voipblaster_register_device(struct usb_voipblaster *dev)
  278. {
  279. #if 0
  280. struct proc_dir_entry *entry;
  281. #endif
  282. dbg("start");
  283. dev->dir = create_proc_entry(dev->serialnum, S_IFDIR, 
  284.      voipblaster_proc_entry);
  285. dbg("mkdir done");
  286. for (p = device_files; p->name; p++) {
  287. dbg("device_files: %s", p->name);
  288. p->dev = dev;
  289. create_proc_read_entry(p->name, 0, dev->dir, 
  290.        read_proc, p);
  291. }
  292. #if 0
  293. entry = create_proc_entry("debug", S_IWUSR | S_IRUGO, dev->dir);
  294. if (entry) {
  295. entry->proc_fops = &proc_debug_operations;
  296. entry->size = 2;
  297. }
  298. #endif
  299. dbg("registered device %s", dev->serialnum);
  300. }
  301. void voipblaster_deregister_device(struct usb_voipblaster *dev)
  302. {
  303. for (p = device_files; p->name; p++) {
  304. dbg("removing device_files : %s", p->name);
  305. remove_proc_entry(p->name, dev->dir);
  306. }
  307. dbg("removing %s", dev->serialnum);
  308. remove_proc_entry(dev->serialnum, voipblaster_proc_entry);
  309. dbg("done");
  310. }
  311. void __init voipblaster_proc_init(void)
  312. {
  313. struct proc_dir_entry *entry;
  314. dbg("start");
  315. voipblaster_proc_entry = create_proc_entry("voipblaster", 
  316.    S_IFDIR, NULL);
  317. dbg("mkdir done");
  318. for (p = simple_ones; p->name; p++) {
  319. dbg("simple one : %s", p->name);
  320. p->dev = NULL;
  321. create_proc_read_entry(p->name, 0, voipblaster_proc_entry, 
  322.        &read_proc, p);
  323. }
  324. entry = create_proc_entry("debug", S_IWUSR | S_IRUGO, 
  325.   voipblaster_proc_entry);
  326. if (entry) {
  327. entry->proc_fops = &proc_debug_operations;
  328. entry->size = 2;
  329. }
  330. entry = create_proc_entry("devices", S_IWUSR | S_IRUGO, 
  331.   voipblaster_proc_entry);
  332. if (entry) {
  333. entry->proc_fops = &proc_devices_operations;
  334. entry->size = 2;
  335. }
  336. dbg("registered simple ones!");
  337. }
  338. void __exit voipblaster_proc_destroy(void)
  339. {
  340. for (p = simple_ones; p->name; p++) {
  341. dbg("simple one : %s", p->name);
  342. remove_proc_entry(p->name, voipblaster_proc_entry);
  343. }
  344. remove_proc_entry("debug", voipblaster_proc_entry);
  345. remove_proc_entry("voipblaster", 0);
  346. voipblaster_proc_entry = NULL;
  347. }
  348. /*
  349.  * Local variables:
  350.  *  c-indent-level: 8
  351.  *  c-basic-offset: 8
  352.  *  tab-width: 8
  353.  * End:
  354.  */