source: mmmux/muxd_hw_rfm12usb.c

Last change on this file was 5758, checked in by soeren, 3 years ago

ook support working

File size: 4.7 KB
Line 
1/*   MMMUX - a device access multiplexing library
2 *
3 *   This program is free software; you can redistribute it and/or modify
4 *   it under the terms of the GNU General Public License as published by
5 *   the Free Software Foundation; either version 2 of the License, or
6 *   (at your option) any later version.
7 *
8 *   This program is distributed in the hope that it will be useful,
9 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
10 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 *   GNU General Public License for more details.
12 *
13 *   You should have received a copy of the GNU General Public License
14 *   along with this program; if not, write to the Free Software
15 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16 *
17 *   Copyright (C) 2012 Soeren Heisrath (forename at surename dot org)
18 */
19
20#include "muxd_hw_rfm12usb.h"
21
22#if MMMUX_USE_RFM12USB == 1
23/* match usb pid/vid numbers
24 */
25int rfm12usb_match_usbid (int in_vid, int in_pid)
26{
27        /* old usb id (same as usbasp!) - will be removed */
28        if (in_vid == 0x16C0 && in_pid == 0x05DC)
29                return 1;
30       
31        /* officially assigned VID/PID pair for rfm12usb */
32        if (in_vid == 0x20a0 && in_pid == 0x4198)
33                return 1;
34       
35        return 0;
36}
37
38/* close the usb connection, remove the hardware from the list */
39void rfm12usb_close (void *in_ctx)
40{
41        rfm12usb_t *rs = ((mmmux_hw_t*) in_ctx)->udata;
42        usb_close (rs->uhandle);
43        rs->uhandle = NULL;
44        mmmux_hw_remove ((mmmux_hw_t*) in_ctx);
45}
46
47ssize_t rfm12usb_tx (void *in_ctx, size_t in_len, void* in_data)
48{
49        size_t txlen = in_len;
50        int rv;
51        rfm12usb_t *rs = ((mmmux_hw_t*) in_ctx)->udata;
52       
53        switch (rs->mode)
54        {
55                case mode_normal:
56                        if (txlen > rs->txlen)
57                                txlen = rs->txlen;
58                       
59                        dbg ("sending %i bytes in NORMAL mode", txlen);
60                        rv = usb_control_msg (rs->uhandle,
61                                USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
62                                RFMUSB_RQ_RADIO_PUT, 1, 0, (char *) in_data, txlen,
63                                DEFAULT_USB_TIMEOUT);
64                break;
65                case mode_ook:
66                        if (txlen < sizeof(rfmusb_ook_t))
67                                return 0;
68
69                        dbg ("sending %i bytes in OOK mode: %02X %02X %02X %02X %02X %02X %02X %02X ...",
70                                txlen,
71                                ((uint8_t *) in_data)[0],
72                                ((uint8_t *) in_data)[1],
73                                ((uint8_t *) in_data)[2],
74                                ((uint8_t *) in_data)[3],
75                                ((uint8_t *) in_data)[4],
76                                ((uint8_t *) in_data)[5],
77                                ((uint8_t *) in_data)[6],
78                                ((uint8_t *) in_data)[7]
79                                );
80                        rv = usb_control_msg (rs->uhandle,
81                                USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
82                                RFMUSB_RQ_OOK_SEND, 1, 0, (char *) in_data, txlen,
83                                DEFAULT_USB_TIMEOUT);
84                break;
85                default:
86                        return 0;
87        }
88
89        if (rv > 0)
90                ((mmmux_hw_t*) in_ctx)->txcount += rv;
91
92        return (ssize_t) rv;
93}
94
95ssize_t rfm12usb_rx (void *in_ctx, size_t in_maxlen, void* out_data)
96{
97        rfm12usb_t *rs = ((mmmux_hw_t*) in_ctx)->udata;
98        int rv;
99
100        memset (out_data, 0x00, in_maxlen);
101
102        rv = usb_control_msg (rs->uhandle,
103                USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
104                RFMUSB_RQ_RADIO_GET, 0, 0, (char *) out_data, in_maxlen,
105                100);
106
107        if (rv > 0)
108        {
109                ((mmmux_hw_t*) in_ctx)->rxcount += rv;
110                return (ssize_t) rv;
111        }
112
113        return 0;
114}
115
116ssize_t rfm12usb_ctrl  (void* in_ctx, mmmux_ctrl_t in_c, void* in_data)
117{
118        rfm12usb_t *rs = ((mmmux_hw_t*) in_ctx)->udata;
119        dbg ("received CTRL code: %llu", in_c);
120        switch (in_c)
121        {
122                case mode_ook:
123                case mode_normal:
124                        rs->mode = in_c;
125                break;
126                default:
127                        return 1;
128        }
129        return 0;
130}
131
132/* walk along the usb busses and devices, search for rfm12usb devices
133 * and add them to the hardware list.
134 */
135int rfm12usb_find (mmmux_sctx_t *in_c)
136{
137        struct usb_bus *bus;
138        struct usb_device *dev;
139        uint_fast8_t c = 0;
140        usb_dev_handle *h = NULL;
141
142        mmmux_hw_t *hws;
143        rfm12usb_t *rs;
144
145        usb_init();
146        usb_find_busses();
147        usb_find_devices();
148
149        bus = usb_get_busses();
150
151        dbg ("...");
152        while (bus != NULL)
153        {
154                for (dev = bus->devices; dev != NULL; dev = dev->next)
155                {
156                        h = usb_open (dev);
157                        if (h == NULL)
158                                continue;
159
160                        if (!rfm12usb_match_usbid (dev->descriptor.idVendor, dev->descriptor.idProduct))
161                                continue;
162
163                        dbg ("found rfm12usb device: vid %04X, pid %04X",
164                                dev->descriptor.idVendor, dev->descriptor.idProduct);
165
166                        hws = malloc (sizeof(mmmux_hw_t));
167                        memset (hws, 0x00, sizeof(mmmux_hw_t));
168
169                        /* store rfm12usb specific data in the udata area */
170                        hws->udata = malloc (sizeof(rfm12usb_t));
171                        rs = (rfm12usb_t *) hws->udata;
172
173                        rs->vid = dev->descriptor.idVendor;
174                        rs->pid = dev->descriptor.idProduct;
175                        rs->txlen = 64; /* XXX hardcoded values for now */
176                        rs->rxlen = 64;
177                        rs->uhandle = h;
178                        rs->mode = mode_normal;
179                        sprintf (hws->name, "RFM12USB device #%u", c++);
180                        hws->init = NULL;
181                        hws->close = rfm12usb_close;
182                        hws->tx = rfm12usb_tx;
183                        hws->rx = rfm12usb_rx;
184                        hws->ctrl = rfm12usb_ctrl;
185                        hws->sdelay = 5000; /* 10ms */
186
187                        mmmux_hw_add (in_c, hws);
188                }
189                bus = bus->next;
190        }
191        return 0;
192}
193#endif
Note: See TracBrowser for help on using the repository browser.