add fiq hooks
[AROS.git] / rom / usb / shellapps / UPSTool.c
blob76d8798deebc99661f5d48f4b1789a408e8da5e4
1 /*
2 *----------------------------------------------------------------------------
3 * UPS Launcher Tool for Poseidon
4 *----------------------------------------------------------------------------
5 * By Chris Hodges <chrisly@platon42.de>
6 */
8 #include "debug.h"
10 #include <proto/dos.h>
11 #include <proto/exec.h>
12 #include <proto/poseidon.h>
14 #include <devices/usb_hid.h>
16 #include "UPSTool.h"
17 #include <string.h>
19 #define ARGS_RAW 0
20 #define ARGS_ID 1
21 #define ARGS_QUERY 2
22 #define ARGS_TOGGLE_BEEPER 3
23 #define ARGS_SHUTDOWN 4
24 #define ARGS_START_BT 5
25 #define ARGS_STOP_BT 6
26 #define ARGS_UNIT 7
27 #define ARGS_SIZEOF 8
29 const char UPSTool_prgname[] = "UPSTool";
30 static const char *template = "RAW/K,ID/S,QUERY/S,TOGGLEBEEPER=TG/S,SHUTDOWN/S,STARTBATTERYTEST=STARTBT/S,STOPBATTERYTEST=STOPBT/S,UNIT/N/K";
31 const char UPSTool_version[] = "$VER: UPSTool 1.0 (12.06.09) by Chris Hodges <chrisly@platon42.de>";
32 static IPTR ArgsArray[ARGS_SIZEOF];
33 static struct RDArgs *ArgsHook = NULL;
35 struct Library *ps;
37 AROS_UFP3(void, releasehook,
38 AROS_UFPA(struct Hook *, hook, A0),
39 AROS_UFPA(APTR, pab, A2),
40 AROS_UFPA(struct NepClassUPS *, nch, A1));
42 struct NepClassUPS * SetupUPS(void);
43 struct NepClassUPS * AllocUPS(struct NepClassUPS *nch);
44 void FreeUPS(struct NepClassUPS *nch);
46 AROS_UFH3(void, releasehook,
47 AROS_UFHA(struct Hook *, hook, A0),
48 AROS_UFHA(APTR, pab, A2),
49 AROS_UFHA(struct NepClassUPS *, nch, A1))
51 AROS_USERFUNC_INIT
52 /*psdAddErrorMsg(RETURN_WARN, (STRPTR) prgname,
53 "UPS killed!");*/
54 Signal(nch->nch_Task, SIGBREAKF_CTRL_C);
55 AROS_USERFUNC_EXIT
58 struct NepClassUPS * SetupUPS(void)
60 struct NepClassUPS *nch;
61 struct PsdDevice *pd = NULL;
62 struct PsdAppBinding *pab;
63 ULONG unit;
65 if(ArgsArray[ARGS_UNIT])
67 unit = *((ULONG *) ArgsArray[ARGS_UNIT]);
68 } else {
69 unit = 0;
75 pd = psdFindDevice(pd,
76 DA_VendorID, 0x0F03,
77 DA_ProductID, 0x0001,
78 TAG_END);
80 } while(pd && (unit--));
82 if(!pd)
84 PutStr("No UPS found!\n");
85 return(NULL);
87 if((nch = psdAllocVec(sizeof(struct NepClassUPS))))
89 nch->nch_Device = pd;
90 nch->nch_ReleaseHook.h_Entry = (APTR) releasehook;
91 pab = psdClaimAppBinding(ABA_Device, pd,
92 ABA_ReleaseHook, &nch->nch_ReleaseHook,
93 ABA_UserData, nch,
94 ABA_ForceRelease, TRUE,
95 TAG_END);
96 if(pab)
98 if(AllocUPS(nch))
100 return(nch);
101 } else {
102 PutStr("Couldn't allocate UPS...\n");
104 psdReleaseAppBinding(pab);
105 } else {
106 PutStr("Couldn't claim binding!\n");
108 psdFreeVec(nch);
110 PutStr("Hohum...\n");
111 } while(TRUE);
112 return(NULL);
115 struct NepClassUPS * AllocUPS(struct NepClassUPS *nch)
117 nch->nch_Task = FindTask(NULL);
119 if((nch->nch_TaskMsgPort = CreateMsgPort()))
121 nch->nch_IF0 = psdFindInterface(nch->nch_Device, NULL, TAG_END);
122 if(nch->nch_IF0)
124 nch->nch_IntEP = psdFindEndpoint(nch->nch_IF0, NULL,
125 EA_IsIn, TRUE,
126 EA_TransferType, USEAF_INTERRUPT,
127 TAG_END);
128 if(nch->nch_IntEP)
130 if((nch->nch_EP0Pipe = psdAllocPipe(nch->nch_Device, nch->nch_TaskMsgPort, NULL)))
132 if((nch->nch_IntPipe = psdAllocPipe(nch->nch_Device, nch->nch_TaskMsgPort, nch->nch_IntEP)))
134 psdSetAttrs(PGA_PIPE, nch->nch_IntPipe,
135 PPA_AllowRuntPackets, TRUE,
136 PPA_NakTimeout, TRUE,
137 PPA_NakTimeoutTime, 5000,
138 TAG_END);
139 return(nch);
141 psdFreePipe(nch->nch_EP0Pipe);
142 PutStr("Couldn't allocate int pipe\n");
143 } else {
144 PutStr("Couldn't allocate default pipe\n");
146 } else {
147 PutStr("Couldn't find endpoint\n");
149 } else {
150 PutStr("Couldn't find interface\n");
152 DeleteMsgPort(nch->nch_TaskMsgPort);
154 return(NULL);
158 void FreeUPS(struct NepClassUPS *nch)
160 APTR pab;
162 psdGetAttrs(PGA_DEVICE, nch->nch_Device,
163 DA_Binding, &pab,
164 TAG_END);
165 psdReleaseAppBinding(pab);
166 psdFreePipe(nch->nch_IntPipe);
167 psdFreePipe(nch->nch_EP0Pipe);
168 DeleteMsgPort(nch->nch_TaskMsgPort);
169 psdFreeVec(nch);
172 BOOL SendCommand(struct NepClassUPS *nch, STRPTR cmd)
174 LONG ioerr;
175 psdSafeRawDoFmt(nch->nch_Buf, 64, "%s\r", cmd);
176 psdPipeSetup(nch->nch_EP0Pipe, URTF_OUT|URTF_CLASS|URTF_INTERFACE, UHR_SET_REPORT, 0x0200, 0);
177 ioerr = psdDoPipe(nch->nch_EP0Pipe, nch->nch_Buf, (ULONG) ((strlen(nch->nch_Buf)+7) & ~7));
178 if(ioerr)
180 Printf("Error sending cmd %s: %s (%ld)\n",
181 cmd,
182 psdNumToStr(NTS_IOERR, ioerr, "unknown"), ioerr);
183 return(FALSE);
185 return(TRUE);
188 STRPTR GetReply(struct NepClassUPS *nch)
190 LONG ioerr;
191 ULONG len;
192 ioerr = psdDoPipe(nch->nch_IntPipe, nch->nch_Reply, 63);
193 if(ioerr)
195 Printf("Error receiving reply: %s (%ld)\n",
196 psdNumToStr(NTS_IOERR, ioerr, "unknown"), ioerr);
197 return(NULL);
199 len = psdGetPipeActual(nch->nch_IntPipe);
200 if((len > 0) && (nch->nch_Reply[len-1] == '\r'))
202 len--; // eliminate trailing cr
204 nch->nch_Reply[len] = 0; // string termination
205 return(nch->nch_Reply);
207 /**************************************************************************/
209 int main(int argc, char *argv[])
211 struct NepClassUPS *nch;
212 ULONG ret = RETURN_ERROR;
213 STRPTR replymsg;
215 if(!(ArgsHook = ReadArgs(template, ArgsArray, NULL)))
217 PutStr("Wrong arguments!\n");
218 return(RETURN_FAIL);
220 ps = OpenLibrary("poseidon.library", 4);
221 if(!ps)
223 FreeArgs(ArgsHook);
224 return(RETURN_FAIL);
226 if(!(nch = SetupUPS()))
228 FreeArgs(ArgsHook);
229 CloseLibrary(ps);
230 return(RETURN_ERROR);
232 if(ArgsArray[ARGS_RAW])
234 if(SendCommand(nch, (STRPTR) ArgsArray[ARGS_RAW]))
236 if((replymsg = GetReply(nch)))
238 Printf("%s\n", replymsg);
239 ret = RETURN_OK;
243 else if(ArgsArray[ARGS_ID])
245 if(SendCommand(nch, "I"))
247 if((replymsg = GetReply(nch)))
249 if(replymsg[0] == '#')
251 Printf("%s\n", replymsg+1);
252 ret = RETURN_OK;
253 } else {
254 PutStr("Bogus reply!\n");
259 else if(ArgsArray[ARGS_QUERY])
261 if(SendCommand(nch, "Q1"))
263 if((replymsg = GetReply(nch)))
265 if(replymsg[0] == '(')
267 Printf("%s\n", replymsg+1);
268 ret = RETURN_OK;
269 } else {
270 PutStr("Bogus reply!\n");
275 else if(ArgsArray[ARGS_TOGGLE_BEEPER])
277 if(SendCommand(nch, "Q"))
279 if((replymsg = GetReply(nch)))
281 PutStr("Beeper toggled!\n");
282 ret = RETURN_OK;
286 else if(ArgsArray[ARGS_SHUTDOWN])
288 if(SendCommand(nch, "S01"))
290 PutStr("Shutting down UPS!\n");
291 ret = RETURN_OK;
294 else if(ArgsArray[ARGS_START_BT])
296 if(SendCommand(nch, "TL"))
298 PutStr("Battery Test started!\n");
299 ret = RETURN_OK;
302 else if(ArgsArray[ARGS_STOP_BT])
304 if(SendCommand(nch, "CT"))
306 PutStr("Battery Test stopped!\n");
307 ret = RETURN_OK;
309 } else {
310 if(SendCommand(nch, "Q1"))
312 if((replymsg = GetReply(nch)))
314 if(*replymsg++ == '(')
316 UWORD cnt = 7;
317 // get status fields
318 while(*replymsg)
320 if(*replymsg++ == ' ')
322 if(!(--cnt))
324 break;
328 if(*replymsg)
330 if((*replymsg == '0') && (replymsg[5] == '0'))
332 PutStr("On line.\n");
333 ret = RETURN_OK;
334 } else {
335 PutStr("On battery!\n");
336 ret = RETURN_WARN;
339 } else {
340 PutStr("Bogus reply!\n");
345 FreeUPS(nch);
346 FreeArgs(ArgsHook);
347 CloseLibrary(ps);
348 return(ret);