2 *----------------------------------------------------------------------------
3 * palmpda class for poseidon
4 *----------------------------------------------------------------------------
5 * By Chris Hodges <chrisly@platon42.de>
10 #include "palmpda.class.h"
13 static const STRPTR libname
= MOD_NAME_STRING
;
16 const APTR DevFuncTable
[] =
18 &AROS_SLIB_ENTRY(devOpen
, dev
, 1),
19 &AROS_SLIB_ENTRY(devClose
, dev
, 2),
20 &AROS_SLIB_ENTRY(devExpunge
, dev
, 3),
21 &AROS_SLIB_ENTRY(devReserved
, dev
, 4),
22 &AROS_SLIB_ENTRY(devBeginIO
, dev
, 5),
23 &AROS_SLIB_ENTRY(devAbortIO
, dev
, 6),
27 static int libInit(LIBBASETYPEPTR nh
)
29 struct NepSerialBase
*ret
= NULL
;
31 KPRINTF(10, ("libInit nh: 0x%08lx SysBase: 0x%08lx\n", nh
, SysBase
));
33 nh
->nh_UtilityBase
= OpenLibrary("utility.library", 39);
35 #define UtilityBase nh->nh_UtilityBase
39 NewList(&nh
->nh_Units
);
41 if((nh
->nh_DevBase
= (struct NepSerDevBase
*) MakeLibrary((APTR
) DevFuncTable
, NULL
, (APTR
) devInit
,
42 sizeof(struct NepSerDevBase
), NULL
)))
44 nh
->nh_DevBase
->np_ClsBase
= nh
;
45 /*NewList(&nh->nh_DummyUnit.unit_MsgPort.mp_MsgList);
46 nh->nh_DummyUnit.unit_MsgPort.mp_SigBit = 0;
47 nh->nh_DummyUnit.unit_MsgPort.mp_SigTask = NULL;
48 nh->nh_DummyUnit.unit_MsgPort.mp_Node.ln_Type = NT_MSGPORT;
49 nh->nh_DummyUnit.unit_MsgPort.mp_Flags = PA_IGNORE;*/
52 AddDevice((struct Device
*) nh
->nh_DevBase
);
53 nh
->nh_DevBase
->np_Library
.lib_OpenCnt
++;
57 KPRINTF(20, ("failed to create palmpda.device\n"));
61 CloseLibrary(UtilityBase
);
64 KPRINTF(20, ("libInit: OpenLibrary(\"utility.library\", 39) failed!\n"));
67 KPRINTF(10, ("libInit: Ok\n"));
68 return(ret
? TRUE
: FALSE
);
71 static int libOpen(LIBBASETYPEPTR nh
)
73 KPRINTF(10, ("libOpen nh: 0x%08lx\n", nh
));
78 static int libExpunge(LIBBASETYPEPTR nh
)
80 struct NepClassSerial
*ncp
;
82 KPRINTF(10, ("libExpunge nh: 0x%08lx\n", nh
));
84 if(nh
->nh_DevBase
->np_Library
.lib_OpenCnt
== 1)
86 KPRINTF(1, ("libExpunge: closelibrary utilitybase 0x%08lx\n",
88 CloseLibrary((struct Library
*) UtilityBase
);
90 ncp
= (struct NepClassSerial
*) nh
->nh_Units
.lh_Head
;
91 while(ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
.ln_Succ
)
93 Remove((struct Node
*) ncp
);
95 ncp
= (struct NepClassSerial
*) nh
->nh_Units
.lh_Head
;
98 nh
->nh_DevBase
->np_Library
.lib_OpenCnt
--;
99 RemDevice((struct Device
*) nh
->nh_DevBase
);
101 KPRINTF(5, ("libExpunge: Unloading done! palmpda.class expunged!\n\n"));
103 KPRINTF(5, ("libExpunge: Could not expunge, LIBF_DELEXP set!\n"));
110 ADD2INITLIB(libInit
, 0)
111 ADD2OPENLIB(libOpen
, 0)
112 ADD2EXPUNGELIB(libExpunge
, 0)
116 * ***********************************************************************
117 * * Library functions *
118 * ***********************************************************************
127 struct AutoBindData ClassBinds
[] =
129 { HANDSPRING_VENDOR_ID
, HANDSPRING_VISOR_ID
},
130 { HANDSPRING_VENDOR_ID
, HANDSPRING_TREO_ID
},
131 { HANDSPRING_VENDOR_ID
, HANDSPRING_TREO600_ID
},
132 { PALM_VENDOR_ID
, PALM_M500_ID
},
133 { PALM_VENDOR_ID
, PALM_M505_ID
},
134 { PALM_VENDOR_ID
, PALM_M515_ID
},
135 { PALM_VENDOR_ID
, PALM_I705_ID
},
136 { PALM_VENDOR_ID
, PALM_M100_ID
},
137 { PALM_VENDOR_ID
, PALM_M125_ID
},
138 { PALM_VENDOR_ID
, PALM_M130_ID
},
139 { PALM_VENDOR_ID
, PALM_TUNGSTEN_T_ID
},
140 { PALM_VENDOR_ID
, PALM_TUNGSTEN_Z_ID
},
141 { PALM_VENDOR_ID
, PALM_ZIRE31_ID
},
142 { PALM_VENDOR_ID
, PALM_ZIRE_ID
},
143 { SONY_VENDOR_ID
, SONY_CLIE_3_5_ID
},
144 { SONY_VENDOR_ID
, SONY_CLIE_4_0_ID
},
145 { SONY_VENDOR_ID
, SONY_CLIE_S360_ID
},
146 { SONY_VENDOR_ID
, SONY_CLIE_4_1_ID
},
147 { SONY_VENDOR_ID
, SONY_CLIE_NX60_ID
},
148 { SONY_VENDOR_ID
, SONY_CLIE_NZ90V_ID
},
149 { SONY_VENDOR_ID
, SONY_CLIE_UX50_ID
},
150 { SONY_VENDOR_ID
, SONY_CLIE_TJ25_ID
},
151 { SAMSUNG_VENDOR_ID
, SAMSUNG_SCH_I330_ID
},
152 { SAMSUNG_VENDOR_ID
, SAMSUNG_SPH_I500_ID
},
153 { GARMIN_VENDOR_ID
, GARMIN_IQUE_3600_ID
},
154 { ACEECA_VENDOR_ID
, ACEECA_MEZ1000_ID
},
155 { KYOCERA_VENDOR_ID
, KYOCERA_7135_ID
},
156 { FOSSIL_VENDOR_ID
, FOSSIL_ABACUS_ID
},
157 { ZODIAC_VENDOR_ID
, ZODIAC_ZODIAC_ID
},
161 /* /// "usbAttemptDeviceBinding()" */
162 struct NepClassSerial
* usbAttemptDeviceBinding(struct NepSerialBase
*nh
, struct PsdDevice
*pd
)
165 struct AutoBindData
*abd
= ClassBinds
;
169 KPRINTF(1, ("nepSerialAttemptDeviceBinding(%08lx)\n", pd
));
170 if((ps
= OpenLibrary("poseidon.library", 4)))
172 psdGetAttrs(PGA_DEVICE
, pd
,
173 DA_VendorID
, &vendid
,
174 DA_ProductID
, &prodid
,
177 while(abd
->abd_VendID
)
179 if((vendid
== abd
->abd_VendID
) && (prodid
== abd
->abd_ProdID
))
181 return(usbForceDeviceBinding(nh
, pd
));
190 /* /// "usbForceDeviceBinding()" */
191 struct NepClassSerial
* usbForceDeviceBinding(struct NepSerialBase
*nh
, struct PsdDevice
*pd
)
194 struct NepClassSerial
*ncp
;
201 struct Task
*tmptask
;
203 KPRINTF(1, ("nepSerialForceDeviceBinding(%08lx)\n", pd
));
204 if((ps
= OpenLibrary("poseidon.library", 4)))
206 psdGetAttrs(PGA_DEVICE
, pd
,
207 DA_ProductID
, &prodid
,
208 DA_VendorID
, &vendid
,
209 DA_ProductName
, &devname
,
212 nLoadClassConfig(nh
);
214 /* Find next free unit number */
216 ncp
= (struct NepClassSerial
*) nh
->nh_Units
.lh_Head
;
217 while(ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
.ln_Succ
)
219 if(ncp
->ncp_UnitNo
== unitno
)
222 ncp
= (struct NepClassSerial
*) nh
->nh_Units
.lh_Head
;
224 ncp
= (struct NepClassSerial
*) ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
.ln_Succ
;
228 ncp
= (struct NepClassSerial
*) nh
->nh_Units
.lh_Head
;
229 while(ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
.ln_Succ
)
231 if((ncp
->ncp_UnitProdID
== prodid
) && (ncp
->ncp_UnitVendorID
== vendid
))
233 unitno
= ncp
->ncp_UnitNo
;
237 ncp
= (struct NepClassSerial
*) ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
.ln_Succ
;
241 /* as units are freed in the expunge-vector, the memory is
242 outside the scope of the poseidon library */
243 if(!(ncp
= AllocVec(sizeof(struct NepClassSerial
), MEMF_PUBLIC
|MEMF_CLEAR
)))
249 /* IORequests may be queued even if the task is gone. */
250 NewList(&ncp
->ncp_Unit
.unit_MsgPort
.mp_MsgList
);
251 NewList(&ncp
->ncp_ReadQueue
);
252 NewList(&ncp
->ncp_WriteQueue
);
253 AddTail(&nh
->nh_Units
, &ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
);
254 ncp
->ncp_DenyRequests
= TRUE
;
256 ncp
->ncp_DevBase
= nh
->nh_DevBase
;
257 ncp
->ncp_UnitNo
= unitno
;
258 ncp
->ncp_Device
= pd
;
259 ncp
->ncp_UnitProdID
= prodid
;
260 ncp
->ncp_UnitVendorID
= vendid
;
263 psdSafeRawDoFmt(buf
, 64, "palmpda.class<%08lx>", ncp
);
264 ncp
->ncp_ReadySignal
= SIGB_SINGLE
;
265 ncp
->ncp_ReadySigTask
= FindTask(NULL
);
266 SetSignal(0, SIGF_SINGLE
);
267 if((tmptask
= psdSpawnSubTask(buf
, nSerialTask
, ncp
)))
269 psdBorrowLocksWait(tmptask
, 1UL<<ncp
->ncp_ReadySignal
);
272 ncp
->ncp_ReadySigTask
= NULL
;
273 //FreeSignal(ncp->ncp_ReadySignal);
274 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
,
275 "This '%s' PDA is hot at %s unit %ld!",
276 devname
, nh
->nh_DevBase
->np_Library
.lib_Node
.ln_Name
,
283 ncp
->ncp_ReadySigTask
= NULL
;
284 //FreeSignal(ncp->ncp_ReadySignal);
285 /* Get rid of unit structure */
287 Remove((struct Node *) ncp);
296 /* /// "usbReleaseDeviceBinding()" */
297 void usbReleaseDeviceBinding(struct NepSerialBase
*nh
, struct NepClassSerial
*ncp
)
302 KPRINTF(1, ("nepSerialReleaseDeviceBinding(%08lx)\n", ncp
));
303 if((ps
= OpenLibrary("poseidon.library", 4)))
306 ncp
->ncp_ReadySignal
= SIGB_SINGLE
;
307 ncp
->ncp_ReadySigTask
= FindTask(NULL
);
310 Signal(ncp
->ncp_Task
, SIGBREAKF_CTRL_C
);
315 Wait(1L<<ncp
->ncp_ReadySignal
);
317 //FreeSignal(ncp->ncp_ReadySignal);
318 psdGetAttrs(PGA_DEVICE
, ncp
->ncp_Device
, DA_ProductName
, &devname
, TAG_END
);
319 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
,
320 "'%s' annealed and broke off.",
328 /* /// "usbGetAttrsA()" */
329 AROS_LH3(LONG
, usbGetAttrsA
,
330 AROS_LHA(ULONG
, type
, D0
),
331 AROS_LHA(APTR
, usbstruct
, A0
),
332 AROS_LHA(struct TagItem
*, tags
, A1
),
333 LIBBASETYPEPTR
, nh
, 5, nep
)
340 KPRINTF(1, ("nepSerialGetAttrsA(%ld, %08lx, %08lx)\n", type
, usbstruct
, tags
));
344 if((ti
= FindTagItem(UCCA_Priority
, tags
)))
346 *((SIPTR
*) ti
->ti_Data
) = 0;
349 if((ti
= FindTagItem(UCCA_Description
, tags
)))
351 *((STRPTR
*) ti
->ti_Data
) = "Palm PDA HotSync via usbpalm.device";
354 if((ti
= FindTagItem(UCCA_HasClassCfgGUI
, tags
)))
356 *((IPTR
*) ti
->ti_Data
) = TRUE
;
359 if((ti
= FindTagItem(UCCA_HasBindingCfgGUI
, tags
)))
361 *((IPTR
*) ti
->ti_Data
) = FALSE
;
364 if((ti
= FindTagItem(UCCA_AfterDOSRestart
, tags
)))
366 *((IPTR
*) ti
->ti_Data
) = FALSE
;
369 if((ti
= FindTagItem(UCCA_UsingDefaultCfg
, tags
)))
371 *((IPTR
*) ti
->ti_Data
) = nh
->nh_UsingDefaultCfg
;
377 if((ti
= FindTagItem(UCBA_UsingDefaultCfg
, tags
)))
379 *((IPTR
*) ti
->ti_Data
) = FALSE
;
390 /* /// "usbSetAttrsA()" */
391 AROS_LH3(LONG
, usbSetAttrsA
,
392 AROS_LHA(ULONG
, type
, D0
),
393 AROS_LHA(APTR
, usbstruct
, A0
),
394 AROS_LHA(struct TagItem
*, tags
, A1
),
395 LIBBASETYPEPTR
, nh
, 6, nep
)
403 /* /// "usbDoMethodA()" */
404 AROS_LH2(IPTR
, usbDoMethodA
,
405 AROS_LHA(ULONG
, methodid
, D0
),
406 AROS_LHA(IPTR
*, methoddata
, A1
),
407 LIBBASETYPEPTR
, nh
, 7, nep
)
411 KPRINTF(10, ("Do Method %ld\n", methodid
));
414 case UCM_AttemptDeviceBinding
:
415 return((IPTR
) usbAttemptDeviceBinding(nh
, (struct PsdDevice
*) methoddata
[0]));
417 case UCM_ForceDeviceBinding
:
418 return((IPTR
) usbForceDeviceBinding(nh
, (struct PsdDevice
*) methoddata
[0]));
420 case UCM_ReleaseDeviceBinding
:
421 usbReleaseDeviceBinding(nh
, (struct NepClassSerial
*) methoddata
[0]);
424 case UCM_OpenCfgWindow
:
425 return(nOpenCfgWindow(nh
));
427 case UCM_ConfigChangedEvent
:
428 nLoadClassConfig(nh
);
439 /* /// "nLoadClassConfig()" */
440 BOOL
nLoadClassConfig(struct NepSerialBase
*nh
)
443 struct ClsGlobalCfg
*cgc
;
444 struct PsdIFFContext
*pic
;
446 KPRINTF(10, ("Loading Class Config...\n"));
451 if(!(ps
= OpenLibrary("poseidon.library", 4)))
456 /* Create default config */
457 nh
->nh_CurrentCGC
.cgc_ChunkID
= AROS_LONG2BE(MAKE_ID('P','A','L','M'));
458 nh
->nh_CurrentCGC
.cgc_Length
= AROS_LONG2BE(sizeof(struct ClsGlobalCfg
)-8);
459 nh
->nh_CurrentCGC
.cgc_ShellStack
= AROS_STACKSIZE
;
460 strcpy(nh
->nh_CurrentCGC
.cgc_ShellCon
, "CON:///130/Palm HotSync Launcher/CLOSE/AUTO/WAIT");
461 strcpy(nh
->nh_CurrentCGC
.cgc_InhibitTask
, "SpitfireHSM");
462 nh
->nh_UsingDefaultCfg
= TRUE
;
463 pic
= psdGetClsCfg(libname
);
466 if((cgc
= psdGetCfgChunk(pic
, AROS_LONG2BE(nh
->nh_CurrentCGC
.cgc_ChunkID
))))
468 CopyMem(((UBYTE
*) cgc
) + 8, ((UBYTE
*) &nh
->nh_CurrentCGC
) + 8, min(AROS_LONG2BE(cgc
->cgc_Length
), AROS_LONG2BE(nh
->nh_CurrentCGC
.cgc_Length
)));
470 nh
->nh_UsingDefaultCfg
= FALSE
;
479 /* /// "nOpenCfgWindow()" */
480 LONG
nOpenCfgWindow(struct NepSerialBase
*nh
)
483 KPRINTF(10, ("Opening GUI...\n"));
484 if(!(ps
= OpenLibrary("poseidon.library", 4)))
491 if((nh
->nh_GUITask
= psdSpawnSubTask(MOD_NAME_STRING
" GUI", nGUITask
, nh
)))
504 /**************************************************************************/
507 #define ps ncp->ncp_Base
509 /* /// "nSetSerialMode()" */
510 void nSetSerialMode(struct NepClassSerial
*ncp
, struct IOExtSer
*ioreq
)
512 ncp
->ncp_IsConfigured
= TRUE
;
516 /* /// "nSerialTask()" */
517 AROS_UFH0(void, nSerialTask
)
521 struct NepClassSerial
*ncp
;
522 struct NepSerialBase
*nh
;
527 struct IOExtSer
*ioreq
;
528 struct IOExtSer
*ioreq2
;
530 if((ncp
= nAllocSerial()))
532 KPRINTF(1, ("nSerialTask()\n"));
534 if(ncp
->ncp_ReadySigTask
)
536 Signal(ncp
->ncp_ReadySigTask
, 1UL<<ncp
->ncp_ReadySignal
);
539 nh
= ncp
->ncp_DevBase
->np_ClsBase
;
542 sigmask
= (1UL<<ncp
->ncp_Unit
.unit_MsgPort
.mp_SigBit
)|(1UL<<ncp
->ncp_TaskMsgPort
->mp_SigBit
)|SIGBREAKF_CTRL_C
;
544 struct MsgPort
*tmpmp
= NULL
;
545 psdGetAttrs(PGA_PIPESTREAM
, ncp
->ncp_EPInStream
, PSA_MessagePort
, &tmpmp
, TAG_END
);
548 sigmask
|= (1UL<<tmpmp
->mp_SigBit
);
551 /* check, if we need to execute a command? */
552 if(*nh
->nh_CurrentCGC
.cgc_Command
)
555 if(nh
->nh_CurrentCGC
.cgc_InhibitTask
)
557 if(FindTask(nh
->nh_CurrentCGC
.cgc_InhibitTask
))
564 struct Library
*dosbase
;
565 if((dosbase
= OpenLibrary("dos.library", 39)))
569 #define DOSBase dosbase
570 if((fhandle
= Open(nh
->nh_CurrentCGC
.cgc_ShellCon
, MODE_READWRITE
)))
572 ioerr
= SystemTags(nh
->nh_CurrentCGC
.cgc_Command
,
576 NP_StackSize
, nh
->nh_CurrentCGC
.cgc_ShellStack
,
580 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) libname
,
581 "Execution of '%s' failed (%ld).",
582 nh
->nh_CurrentCGC
.cgc_Command
, ioerr
);
585 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
,
587 nh
->nh_CurrentCGC
.cgc_Command
);
590 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) libname
,
591 "Console '%s' could not be opened!",
592 nh
->nh_CurrentCGC
.cgc_ShellCon
);
594 CloseLibrary(dosbase
);
599 //nServerRitual(ncp);
602 while((ioreq
= (struct IOExtSer
*) GetMsg(&ncp
->ncp_Unit
.unit_MsgPort
)))
604 KPRINTF(5, ("command ioreq: 0x%08lx cmd: %lu len: %ld\n",
605 ioreq
, ioreq
->IOSer
.io_Command
, ioreq
->IOSer
.io_Length
));
606 switch(ioreq
->IOSer
.io_Command
)
609 psdStreamFlush(ncp
->ncp_EPOutStream
);
610 ReplyMsg((struct Message
*) ioreq
);
614 /* Reset does a flush too */
617 ioreq2
= (struct IOExtSer
*) ncp
->ncp_WriteQueue
.lh_Head
;
618 while(ioreq2
->IOSer
.io_Message
.mn_Node
.ln_Succ
)
620 Remove((struct Node
*) ioreq2
);
621 ioreq2
->IOSer
.io_Error
= IOERR_ABORTED
;
622 ReplyMsg((struct Message
*) ioreq2
);
623 ioreq2
= (struct IOExtSer
*) ncp
->ncp_WriteQueue
.lh_Head
;
625 ioreq2
= (struct IOExtSer
*) ncp
->ncp_ReadQueue
.lh_Head
;
626 while(ioreq2
->IOSer
.io_Message
.mn_Node
.ln_Succ
)
628 Remove((struct Node
*) ioreq2
);
629 ioreq2
->IOSer
.io_Error
= IOERR_ABORTED
;
630 ReplyMsg((struct Message
*) ioreq2
);
631 ioreq2
= (struct IOExtSer
*) ncp
->ncp_ReadQueue
.lh_Head
;
633 ReplyMsg((struct Message
*) ioreq
);
637 case SDCMD_SETPARAMS
:
638 nSetSerialMode(ncp
, ioreq
);
639 ReplyMsg((struct Message
*) ioreq
);
643 ioreq
->io_Status
= (1<<5);
645 psdGetAttrs(PGA_PIPESTREAM
, ncp
->ncp_EPInStream
,
646 PSA_BytesPending
, &pending
,
648 ioreq
->IOSer
.io_Actual
= pending
;
649 if(!ioreq
->IOSer
.io_Actual
)
651 ioreq
->IOSer
.io_Actual
= 1;
653 ReplyMsg((struct Message
*) ioreq
);
657 psdStreamFlush(ncp
->ncp_EPInStream
);
658 psdPipeSetup(ncp
->ncp_EP0Pipe
, URTF_IN
|URTF_VENDOR
|URTF_ENDPOINT
,
659 UPR_CLOSE_NOTIFICATION
, 0, 0);
660 ioerr
= psdDoPipe(ncp
->ncp_EP0Pipe
, NULL
, 0);
663 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) libname
,
664 "CLOSE_NOTIFICATION failed: %s (%ld)",
665 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
667 ReplyMsg((struct Message
*) ioreq
);
671 ioreq
->IOSer
.io_Error
= IOERR_NOCMD
;
672 ReplyMsg((struct Message
*) ioreq
);
676 if(!ncp
->ncp_DevSuspend
)
679 ioreq
= (struct IOExtSer
*) ncp
->ncp_ReadQueue
.lh_Head
;
680 while(ioreq
->IOSer
.io_Message
.mn_Node
.ln_Succ
)
682 if(!ncp
->ncp_IsConfigured
)
685 nSetSerialMode(ncp
, ioreq
);
688 Remove((struct Node
*) ioreq
);
690 ioreq
->IOSer
.io_Actual
= psdStreamRead(ncp
->ncp_EPInStream
, ioreq
->IOSer
.io_Data
, ioreq
->IOSer
.io_Length
);
691 ioerr
= psdGetStreamError(ncp
->ncp_EPInStream
);
692 if(ioerr
== UHIOERR_NAKTIMEOUT
)
695 AddHead(&ncp
->ncp_ReadQueue
, &ioreq
->IOSer
.io_Message
.mn_Node
);
700 ioreq
->IOSer
.io_Error
= SerErr_LineErr
;
702 ioreq
->IOSer
.io_Error
= ioerr
;
704 ReplyMsg((struct Message
*) ioreq
);
706 psdGetAttrs(PGA_PIPESTREAM
, ncp
->ncp_EPInStream
,
707 PSA_BytesPending
, &pending
,
710 ioreq
= (struct IOExtSer
*) ncp
->ncp_ReadQueue
.lh_Head
;
712 ioreq
= (struct IOExtSer
*) ncp
->ncp_WriteQueue
.lh_Head
;
713 while(ioreq
->IOSer
.io_Message
.mn_Node
.ln_Succ
)
715 if(!ncp
->ncp_IsConfigured
)
718 nSetSerialMode(ncp
, ioreq
);
721 Remove((struct Node
*) ioreq
);
722 ncp
->ncp_WritePending
= ioreq
;
724 ioreq
->IOSer
.io_Actual
= psdStreamWrite(ncp
->ncp_EPOutStream
, ioreq
->IOSer
.io_Data
, ioreq
->IOSer
.io_Length
);
725 ncp
->ncp_WritePending
= NULL
;
726 ioerr
= psdGetStreamError(ncp
->ncp_EPInStream
);
729 ioreq
->IOSer
.io_Error
= SerErr_LineErr
;
731 ioreq
->IOSer
.io_Error
= ioerr
;
733 ReplyMsg((struct Message
*) ioreq
);
735 ioreq
= (struct IOExtSer
*) ncp
->ncp_WriteQueue
.lh_Head
;
739 sigs
= Wait(sigmask
);
740 } while(!(sigs
& SIGBREAKF_CTRL_C
));
741 KPRINTF(1, ("Going down...\n"));
742 /* Now remove all requests still pending *anywhere* */
743 ncp
->ncp_DenyRequests
= TRUE
;
744 /* Read/Write queues */
746 ioreq
= (struct IOExtSer
*) ncp
->ncp_WriteQueue
.lh_Head
;
747 while(ioreq
->IOSer
.io_Message
.mn_Node
.ln_Succ
)
749 Remove((struct Node
*) ioreq
);
750 ioreq
->IOSer
.io_Error
= IOERR_ABORTED
;
751 ReplyMsg((struct Message
*) ioreq
);
752 ioreq
= (struct IOExtSer
*) ncp
->ncp_WriteQueue
.lh_Head
;
754 ioreq
= (struct IOExtSer
*) ncp
->ncp_ReadQueue
.lh_Head
;
755 while(ioreq
->IOSer
.io_Message
.mn_Node
.ln_Succ
)
757 Remove((struct Node
*) ioreq
);
758 ioreq
->IOSer
.io_Error
= IOERR_ABORTED
;
759 ReplyMsg((struct Message
*) ioreq
);
760 ioreq
= (struct IOExtSer
*) ncp
->ncp_ReadQueue
.lh_Head
;
763 while((ioreq
= (struct IOExtSer
*) GetMsg(&ncp
->ncp_Unit
.unit_MsgPort
)))
765 ioreq
->IOSer
.io_Error
= IOERR_ABORTED
;
766 ReplyMsg((struct Message
*) ioreq
);
769 KPRINTF(20, ("Going down the river!\n"));
777 /* /// "nAllocSerial()" */
778 struct NepClassSerial
* nAllocSerial(void)
780 struct Task
*thistask
;
781 struct NepClassSerial
*ncp
;
786 thistask
= FindTask(NULL
);
787 ncp
= thistask
->tc_UserData
;
790 if(!(ncp
->ncp_Base
= OpenLibrary("poseidon.library", 4)))
795 if(!(ncp
->ncp_Interface
= psdFindInterface(ncp
->ncp_Device
, NULL
, TAG_END
)))
797 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) libname
, "No interface found?!?");
801 if((ncp
->ncp_TaskMsgPort
= CreateMsgPort()))
803 if((ncp
->ncp_EP0Pipe
= psdAllocPipe(ncp
->ncp_Device
, ncp
->ncp_TaskMsgPort
, NULL
)))
805 psdPipeSetup(ncp
->ncp_EP0Pipe
, URTF_IN
|URTF_VENDOR
|URTF_ENDPOINT
,
806 UPR_GET_EXT_CONNECTION_INFORMATION
, 0, 0);
807 ioerr
= psdDoPipe(ncp
->ncp_EP0Pipe
, &ncp
->ncp_ExtConnectInfo
, sizeof(struct ExtConnectInfo
));
808 ncp
->ncp_ExtConnectInfo
.Streams
[0].FctID
= AROS_LONG2LE(ncp
->ncp_ExtConnectInfo
.Streams
[0].FctID
);
809 ncp
->ncp_ExtConnectInfo
.Streams
[1].FctID
= AROS_LONG2LE(ncp
->ncp_ExtConnectInfo
.Streams
[1].FctID
);
812 for(cnt
= 0; cnt
< ncp
->ncp_ExtConnectInfo
.NumPorts
; cnt
++)
814 switch(ncp
->ncp_ExtConnectInfo
.Streams
[cnt
].FctID
)
816 case MAKE_ID('s','y','n','c'):
817 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
, "There's that hotsync port (%ld) we've been looking for!", cnt
+1);
818 ncp
->ncp_HotsyncPort
= cnt
+1;
819 if(ncp
->ncp_ExtConnectInfo
.DiffEndPoints
)
821 ncp
->ncp_EPInNum
= (ncp
->ncp_ExtConnectInfo
.Streams
[cnt
].EPInfo
>> 4) & 15;
822 ncp
->ncp_EPOutNum
= ncp
->ncp_ExtConnectInfo
.Streams
[cnt
].EPInfo
& 15;
824 ncp
->ncp_EPInNum
= ncp
->ncp_EPOutNum
= ncp
->ncp_ExtConnectInfo
.Streams
[cnt
].Port
;
831 memcpy(fctid
, &ncp
->ncp_ExtConnectInfo
.Streams
[cnt
].FctID
, 4);
833 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) libname
, "Unknown function %s at PDA port %ld!", fctid
, cnt
+1);
838 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) libname
,
839 "GET_EXT_CONNECTION_INFORMATION failed: %s (%ld)",
840 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
841 psdPipeSetup(ncp
->ncp_EP0Pipe
, URTF_IN
|URTF_VENDOR
|URTF_ENDPOINT
,
842 UPR_GET_CONNECTION_INFORMATION
, 0, 0);
843 ioerr
= psdDoPipe(ncp
->ncp_EP0Pipe
, &ncp
->ncp_ConnectInfo
, sizeof(struct ConnectInfo
));
844 ncp
->ncp_ConnectInfo
.NumPorts
= AROS_WORD2LE(ncp
->ncp_ConnectInfo
.NumPorts
);
847 for(cnt
= 0; cnt
< ncp
->ncp_ConnectInfo
.NumPorts
; cnt
++)
849 switch(ncp
->ncp_ConnectInfo
.Streams
[cnt
].FctID
)
851 case PALM_FUNCTION_GENERIC
:
852 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
, "This PDA has a generic port (%ld)!", cnt
+1);
853 //ncp->ncp_HotsyncPort = cnt+1;
856 case PALM_FUNCTION_DEBUGGER
:
857 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
, "Uuuuh, your PDA has a debugging port (%ld) aswell!", cnt
+1);
860 case PALM_FUNCTION_HOTSYNC
:
861 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
, "There's that hotsync port (%ld) we've been looking for!", cnt
+1);
862 ncp
->ncp_HotsyncPort
= cnt
+1;
863 ncp
->ncp_EPOutNum
= cnt
+1;
864 ncp
->ncp_EPInNum
= cnt
+1;
867 case PALM_FUNCTION_CONSOLE
:
868 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
, "Your PDA supplies a console port (%ld). Nice!", cnt
+1);
871 case PALM_FUNCTION_REMOTE_FILE_SYS
:
872 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
, "Holy Cow! There's a remote file system port (%ld)!", cnt
+1);
876 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) libname
,
877 "Unknown function %02lx at PDA port %ld!",
878 ncp
->ncp_ConnectInfo
.Streams
[cnt
].FctID
,
884 psdPipeSetup(ncp
->ncp_EP0Pipe
, URTF_IN
|URTF_VENDOR
|URTF_ENDPOINT
,
885 UPR_REQUEST_BYTES_AVAILABLE
, 0, 5);
886 ioerr
= psdDoPipe(ncp
->ncp_EP0Pipe
, &dummy
, 2);
889 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) libname
,
890 "REQUEST_BYTES_AVAILABLE failed: %s (%ld)",
891 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
894 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) libname
,
895 "GET_CONNECTION_INFORMATION failed: %s (%ld)",
896 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
899 if(ncp
->ncp_HotsyncPort
)
901 ncp
->ncp_EPIn
= psdFindEndpoint(ncp
->ncp_Interface
, NULL
,
902 EA_EndpointNum
, ncp
->ncp_EPInNum
,
904 EA_TransferType
, USEAF_BULK
,
906 ncp
->ncp_EPOut
= psdFindEndpoint(ncp
->ncp_Interface
, NULL
,
907 EA_EndpointNum
, ncp
->ncp_EPOutNum
,
909 EA_TransferType
, USEAF_BULK
,
911 if(ncp
->ncp_EPIn
&& ncp
->ncp_EPOut
)
913 ncp
->ncp_AbortSignal
= AllocSignal(-1);
914 if((ncp
->ncp_EPOutStream
= psdOpenStream(ncp
->ncp_EPOut
,
915 PSA_BufferedWrite
, FALSE
,
916 PSA_NoZeroPktTerm
, TRUE
,
917 PSA_NakTimeout
, TRUE
,
918 PSA_NakTimeoutTime
, 5000,
919 PSA_AbortSigMask
, (1UL<<ncp
->ncp_AbortSignal
)|SIGBREAKF_CTRL_C
,
922 if((ncp
->ncp_EPInStream
= psdOpenStream(ncp
->ncp_EPIn
,
923 PSA_ReadAhead
, FALSE
,
924 PSA_BufferedRead
, TRUE
,
925 PSA_NumPipes
, NUMREADPIPES
,
926 PSA_BufferSize
, DEFREADBUFLEN
,
927 PSA_AllowRuntPackets
, TRUE
,
928 PSA_DoNotWait
, FALSE
,
929 PSA_NakTimeout
, TRUE
,
930 PSA_NakTimeoutTime
, 5000,
931 PSA_AbortSigMask
, SIGBREAKF_CTRL_C
,
934 ncp
->ncp_Unit
.unit_MsgPort
.mp_SigBit
= AllocSignal(-1);
935 ncp
->ncp_Unit
.unit_MsgPort
.mp_SigTask
= thistask
;
936 ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
.ln_Type
= NT_MSGPORT
;
937 ncp
->ncp_Unit
.unit_MsgPort
.mp_Flags
= PA_SIGNAL
;
938 ncp
->ncp_WritePending
= NULL
;
939 ncp
->ncp_Task
= thistask
;
942 psdCloseStream(ncp
->ncp_EPOutStream
);
944 FreeSignal(ncp
->ncp_AbortSignal
);
946 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) libname
, "Unable to find endpoints for hotsync port!");
949 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) libname
, "Sorry, there's no hotsync port! Giving up!");
951 psdFreePipe(ncp
->ncp_EP0Pipe
);
953 DeleteMsgPort(ncp
->ncp_TaskMsgPort
);
956 CloseLibrary(ncp
->ncp_Base
);
958 ncp
->ncp_Task
= NULL
;
959 if(ncp
->ncp_ReadySigTask
)
961 Signal(ncp
->ncp_ReadySigTask
, 1UL<<ncp
->ncp_ReadySignal
);
967 /* /// "nFreeSerial()" */
968 void nFreeSerial(struct NepClassSerial
*ncp
)
970 struct IOStdReq
*ioreq
;
972 FreeSignal(ncp
->ncp_AbortSignal
);
973 ncp
->ncp_AbortSignal
= -1;
974 /* Disable the message port, messages may still be queued */
975 ncp
->ncp_Unit
.unit_MsgPort
.mp_SigTask
= NULL
;
976 ncp
->ncp_Unit
.unit_MsgPort
.mp_Flags
= PA_IGNORE
;
977 FreeSignal((LONG
) ncp
->ncp_Unit
.unit_MsgPort
.mp_SigBit
);
978 // get rid of all messages that still have appeared here
979 while((ioreq
= (struct IOStdReq
*) GetMsg(&ncp
->ncp_Unit
.unit_MsgPort
)))
981 ioreq
->io_Error
= IOERR_ABORTED
;
982 ReplyMsg((struct Message
*) ioreq
);
986 psdCloseStream(ncp
->ncp_EPInStream
);
987 psdCloseStream(ncp
->ncp_EPOutStream
);
988 psdFreePipe(ncp
->ncp_EP0Pipe
);
990 DeleteMsgPort(ncp
->ncp_TaskMsgPort
);
991 CloseLibrary(ncp
->ncp_Base
);
993 ncp
->ncp_Task
= NULL
;
994 if(ncp
->ncp_ReadySigTask
)
996 Signal(ncp
->ncp_ReadySigTask
, 1UL<<ncp
->ncp_ReadySignal
);
1001 /**************************************************************************/
1003 /* /// "nGUITask()" */
1004 AROS_UFH0(void, nGUITask
)
1008 struct Task
*thistask
;
1009 struct NepSerialBase
*nh
;
1012 thistask
= FindTask(NULL
);
1014 #define ps nh->nh_PsdBase
1015 #undef IntuitionBase
1016 #define IntuitionBase nh->nh_IntBase
1017 #undef MUIMasterBase
1018 #define MUIMasterBase nh->nh_MUIBase
1020 nh
= thistask
->tc_UserData
;
1021 ++nh
->nh_Library
.lib_OpenCnt
;
1022 if(!(MUIMasterBase
= OpenLibrary(MUIMASTER_NAME
, MUIMASTER_VMIN
)))
1024 KPRINTF(10, ("Couldn't open muimaster.library.\n"));
1025 nGUITaskCleanup(nh
);
1029 if(!(IntuitionBase
= OpenLibrary("intuition.library", 39)))
1031 KPRINTF(10, ("Couldn't open intuition.library.\n"));
1032 nGUITaskCleanup(nh
);
1035 if(!(ps
= OpenLibrary("poseidon.library", 4)))
1037 KPRINTF(10, ("Couldn't open poseidon.library.\n"));
1038 nGUITaskCleanup(nh
);
1042 nh
->nh_App
= ApplicationObject
,
1043 MUIA_Application_Title
, (IPTR
)libname
,
1044 MUIA_Application_Version
, (IPTR
)VERSION_STRING
,
1045 MUIA_Application_Copyright
, (IPTR
)"©2004-2009 Chris Hodges",
1046 MUIA_Application_Author
, (IPTR
)"Chris Hodges <chrisly@platon42.de>",
1047 MUIA_Application_Description
, (IPTR
)"Settings for the palmpda.class",
1048 MUIA_Application_Base
, (IPTR
)"PALMPDA",
1049 MUIA_Application_HelpFile
, (IPTR
)"HELP:Poseidon.guide",
1050 MUIA_Application_Menustrip
, (IPTR
)MenustripObject
,
1051 Child
, (IPTR
)MenuObjectT((IPTR
)"Project"),
1052 Child
, (IPTR
)(nh
->nh_AboutMI
= MenuitemObject
,
1053 MUIA_Menuitem_Title
, (IPTR
)"About...",
1054 MUIA_Menuitem_Shortcut
, (IPTR
)"?",
1057 Child
, (IPTR
)MenuObjectT((IPTR
)"Settings"),
1058 Child
, (IPTR
)(nh
->nh_UseMI
= MenuitemObject
,
1059 MUIA_Menuitem_Title
, (IPTR
)"Save",
1060 MUIA_Menuitem_Shortcut
, (IPTR
)"S",
1062 Child
, (IPTR
)MenuitemObject
,
1063 MUIA_Menuitem_Title
, (IPTR
)NM_BARLABEL
,
1065 Child
, (IPTR
)(nh
->nh_MUIPrefsMI
= MenuitemObject
,
1066 MUIA_Menuitem_Title
, (IPTR
)"MUI Settings",
1067 MUIA_Menuitem_Shortcut
, (IPTR
)"M",
1072 SubWindow
, (IPTR
)(nh
->nh_MainWindow
= WindowObject
,
1073 MUIA_Window_ID
, MAKE_ID('M','A','I','N'),
1074 MUIA_Window_Title
, (IPTR
)libname
,
1075 MUIA_HelpNode
, (IPTR
)libname
,
1077 WindowContents
, (IPTR
)VGroup
,
1078 /* Child, actionobj = NewObject(ActionClass->mcc_Class, 0,
1081 Child
, (IPTR
)ColGroup(2), GroupFrameT((IPTR
)"Global Settings"),
1082 Child
, (IPTR
)Label((IPTR
) "Shell console window:"),
1083 Child
, (IPTR
)(nh
->nh_ConWindowObj
= StringObject
,
1086 MUIA_String_AdvanceOnCR
, TRUE
,
1087 MUIA_String_Contents
, (IPTR
)nh
->nh_CurrentCGC
.cgc_ShellCon
,
1088 MUIA_String_MaxLen
, 128,
1090 Child
, (IPTR
)Label((IPTR
) "Shell default stack:"),
1091 Child
, (IPTR
)(nh
->nh_ShellStackObj
= StringObject
,
1094 MUIA_String_AdvanceOnCR
, TRUE
,
1095 MUIA_String_Integer
, nh
->nh_CurrentCGC
.cgc_ShellStack
,
1096 MUIA_String_Accept
, (IPTR
)"0123456789",
1098 Child
, (IPTR
)Label((IPTR
) "Command:"),
1099 Child
, (IPTR
)PopaslObject
,
1100 MUIA_Popstring_String
, (IPTR
)(nh
->nh_ShellComObj
= StringObject
,
1103 MUIA_String_AdvanceOnCR
, TRUE
,
1104 MUIA_String_Contents
, (IPTR
)nh
->nh_CurrentCGC
.cgc_Command
,
1105 MUIA_String_MaxLen
, 256,
1107 MUIA_Popstring_Button
, (IPTR
)PopButton(MUII_PopFile
),
1108 ASLFR_TitleText
, (IPTR
)"Select an executable...",
1110 Child
, (IPTR
)Label((IPTR
) "Don't launch, when this task found:"),
1111 Child
, (IPTR
)(nh
->nh_InhibitTaskObj
= StringObject
,
1114 MUIA_String_AdvanceOnCR
, TRUE
,
1115 MUIA_String_Contents
, (IPTR
)nh
->nh_CurrentCGC
.cgc_InhibitTask
,
1116 MUIA_String_MaxLen
, 64,
1119 Child
, (IPTR
)VSpace(0),
1120 Child
, (IPTR
)HGroup
,
1121 MUIA_Group_SameWidth
, TRUE
,
1122 Child
, (IPTR
)(nh
->nh_UseObj
= TextObject
, ButtonFrame
,
1123 MUIA_Background
, MUII_ButtonBack
,
1125 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
1126 MUIA_Text_Contents
, (IPTR
)"\33c Save ",
1128 Child
, (IPTR
)(nh
->nh_CloseObj
= TextObject
, ButtonFrame
,
1129 MUIA_Background
, MUII_ButtonBack
,
1131 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
1132 MUIA_Text_Contents
, (IPTR
)"\33c Use ",
1141 KPRINTF(10, ("Couldn't create application\n"));
1142 nGUITaskCleanup(nh
);
1145 DoMethod(nh
->nh_MainWindow
, MUIM_Notify
, MUIA_Window_CloseRequest
, TRUE
,
1146 nh
->nh_App
, 2, MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
);
1147 DoMethod(nh
->nh_UseObj
, MUIM_Notify
, MUIA_Pressed
, FALSE
,
1148 nh
->nh_App
, 2, MUIM_Application_ReturnID
, ID_STORE_CONFIG
);
1149 DoMethod(nh
->nh_CloseObj
, MUIM_Notify
, MUIA_Pressed
, FALSE
,
1150 nh
->nh_App
, 2, MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
);
1152 DoMethod(nh
->nh_AboutMI
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
1153 nh
->nh_App
, 2, MUIM_Application_ReturnID
, ID_ABOUT
);
1154 DoMethod(nh
->nh_UseMI
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
1155 nh
->nh_App
, 2, MUIM_Application_ReturnID
, ID_STORE_CONFIG
);
1156 DoMethod(nh
->nh_MUIPrefsMI
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
1157 nh
->nh_App
, 2, MUIM_Application_OpenConfigWindow
, 0);
1166 get(nh
->nh_App
, MUIA_Application_Iconified
, &iconify
);
1167 set(nh
->nh_MainWindow
, MUIA_Window_Open
, TRUE
);
1168 get(nh
->nh_MainWindow
, MUIA_Window_Open
, &isopen
);
1169 if(!(isopen
|| iconify
))
1171 nGUITaskCleanup(nh
);
1177 retid
= DoMethod(nh
->nh_App
, MUIM_Application_NewInput
, &sigs
);
1180 case ID_STORE_CONFIG
:
1181 case MUIV_Application_ReturnID_Quit
:
1183 STRPTR tmpstr
= NULL
;
1185 get(nh
->nh_ShellStackObj
, MUIA_String_Integer
, &nh
->nh_CurrentCGC
.cgc_ShellStack
);
1186 get(nh
->nh_ConWindowObj
, MUIA_String_Contents
, &tmpstr
);
1187 strncpy(nh
->nh_CurrentCGC
.cgc_ShellCon
, tmpstr
, 127);
1188 get(nh
->nh_ShellComObj
, MUIA_String_Contents
, &tmpstr
);
1189 strncpy(nh
->nh_CurrentCGC
.cgc_Command
, tmpstr
, 255);
1190 get(nh
->nh_InhibitTaskObj
, MUIA_String_Contents
, &tmpstr
);
1191 strncpy(nh
->nh_CurrentCGC
.cgc_InhibitTask
, tmpstr
, 63);
1192 pic
= psdGetClsCfg(libname
);
1195 psdSetClsCfg(libname
, NULL
);
1196 pic
= psdGetClsCfg(libname
);
1200 if(psdAddCfgEntry(pic
, &nh
->nh_CurrentCGC
))
1202 if(retid
!= MUIV_Application_ReturnID_Quit
)
1204 psdSaveCfgToDisk(NULL
, FALSE
);
1206 retid
= MUIV_Application_ReturnID_Quit
;
1212 MUI_RequestA(nh
->nh_App
, nh
->nh_MainWindow
, 0, NULL
, "Hot stuff!", VERSION_STRING
, NULL
);
1215 if(retid
== MUIV_Application_ReturnID_Quit
)
1221 sigs
= Wait(sigs
| sigmask
| SIGBREAKF_CTRL_C
);
1222 if(sigs
& SIGBREAKF_CTRL_C
)
1228 set(nh
->nh_MainWindow
, MUIA_Window_Open
, FALSE
);
1230 nGUITaskCleanup(nh
);
1236 /* /// "nGUITaskCleanup()" */
1237 void nGUITaskCleanup(struct NepSerialBase
*nh
)
1241 MUI_DisposeObject(nh
->nh_App
);
1246 CloseLibrary(MUIMasterBase
);
1247 MUIMasterBase
= NULL
;
1251 CloseLibrary(IntuitionBase
);
1252 IntuitionBase
= NULL
;
1260 nh
->nh_GUITask
= NULL
;
1261 --nh
->nh_Library
.lib_OpenCnt
;