jcs
/wifi_da
/amendments
/10
*: Bugfixes, mask password entry, add debug logger
Properly handle unassociated state switching to associated.
Maintain a separate list of menu networks to be able to redraw the
menu at any time.
jcs made amendment 10 11 months ago
--- main.c Thu Sep 21 13:29:51 2023
+++ main.c Fri Oct 20 22:49:22 2023
@@ -20,16 +20,19 @@
#include "wi-fi.h"
/* device control entry */
-DCtlPtr dce;
+DCtlPtr dce = NULL;
short da_state = STATE_CLOSED;
short wifi_scsi_id = WIFI_SCSI_ID_FINDING;
+unsigned long wifi_scan_started = 0;
struct wifi_network_entry wifi_cur_info = { 0 };
struct wifi_network_entry wifi_scan_networks[10] = { 0 };
MenuHandle menu, apple_menu;
short menuID;
WindowPtr win = 0L;
Cursor watch;
+short logger_y = 12;
+WindowPtr logger = 0;
short main(cntrlParam *p, DCtlPtr d, short n);
void da_open(void);
@@ -38,6 +41,9 @@ void da_close(void);
bool handle_menu(short i);
void handle_event(EventRecord *e);
void handle_timer(void);
+#ifdef DEBUG_LOGGING
+void logger_vprintf(const char *format, va_list ap);
+#endif
short
main(cntrlParam *p, DCtlPtr d, short n)
@@ -51,6 +57,9 @@ main(cntrlParam *p, DCtlPtr d, short n)
return 0;
}
+ if (dce == NULL)
+ util_init(d);
+
dce = d;
dce->dCtlFlags &= ~dCtlEnable;
@@ -82,10 +91,23 @@ void
da_open(void)
{
CursHandle h;
+ Rect bounds;
bool dispose;
dce->dCtlFlags |= dNeedLock | dNeedGoodBye;
-
+
+#ifdef DEBUG_LOGGING
+ if (!logger) {
+ bounds.top = 150;
+ bounds.bottom = 320;
+ bounds.left = 20;
+ bounds.right = 400;
+ logger = NewWindow(0L, &bounds, "\pLogger", true, rDocProc, 0L,
+ true, 0L);
+ ((WindowPeek)logger)->windowKind = dce->dCtlRefNum;
+ }
+#endif
+
if (win)
SelectWindow(win);
@@ -100,7 +122,7 @@ da_open(void)
h = GetCursor(watchCursor);
dispose = (GetHandleSize((Handle)h) == 0);
SetResLoad(true);
- BlockMove(*(h=GetCursor(watchCursor)), &watch, sizeof(Cursor));
+ BlockMove(*(h = GetCursor(watchCursor)), &watch, sizeof(Cursor));
if (dispose)
ReleaseResource((Handle)h);
@@ -153,7 +175,7 @@ handle_menu(short i)
switch (i) {
case MAIN_MENU_ABOUT_ID:
- about();
+ wifi_about();
break;
case MAIN_MENU_QUIT_ID:
CloseDriver(dce->dCtlRefNum);
@@ -208,10 +230,13 @@ handle_timer(void)
if ((Ticks - last_update) < (60 * 1))
break;
last_update = Ticks;
- if (!scsi_wifi_scan_finished(wifi_scsi_id))
- break;
+ if (!scsi_wifi_scan_finished(wifi_scsi_id)) {
+ if (Time - wifi_scan_started <= 5)
+ break;
+ warn("Wi-Fi scan failed to finish, canceling");
+ }
da_state = STATE_IDLE;
- update_wifi_ssid_list();
+ update_wifi_ssid_list(true);
break;
case STATE_IDLE:
/* refresh RSSI every 5 seconds */
@@ -225,117 +250,37 @@ handle_timer(void)
}
}
-long
-OwnedResourceID(long n)
-{
- return (0xc000 + ((~(dce->dCtlRefNum)) << 5) + n);
-}
-
+#ifdef DEBUG_LOGGING
void
-warn(char *format, ...)
+logger_printf(const char *format, ...)
{
- static char warn_str[255];
- va_list ap;
-
- va_start(ap, format);
- vsprintf(warn_str, format, ap);
- va_end(ap);
-
- CtoPstr(warn_str);
- ParamText(warn_str, "", "", "");
- Alert(OwnedResourceID(ERROR_DIALOG_ID), 0L);
+ va_list va;
+
+ if (!logger)
+ return;
+
+ va_start(va, format);
+ logger_vprintf(format, va);
+ va_end(va);
}
void
-CenterDialog(DialogPtr dp, bool titlebar)
+logger_vprintf(const char *format, va_list ap)
{
- GrafPtr tport;
- Rect bounds;
- short width, height;
-
- /* screenBits is not available from a DA */
- tport = (GrafPtr)NewPtr(sizeof(GrafPort));
- OpenPort(tport);
+ static char buf[512];
+ GrafPtr savePort;
+ ssize_t len;
- width = ((DialogPeek)dp)->window.port.portRect.right;
- height = ((DialogPeek)dp)->window.port.portRect.bottom;
-
- bounds.left = ((tport->portRect.right - tport->portRect.left) / 2) -
- (width / 2);
- bounds.top = ((tport->portRect.bottom - tport->portRect.top) / 2) -
- (height / 2) + (titlebar ? GetMBarHeight() : 0);
- bounds.right = bounds.left + width;
- bounds.bottom = bounds.top + height;
+ len = vsprintf(buf, format, ap);
- ClosePort(tport);
+ GetPort(&savePort);
+ SetPort(logger);
+ MoveTo(4, logger_y);
+ TextFont(geneva);
+ TextSize(9);
+ DrawText(buf, 0, len);
+ logger_y += 10;
- MoveWindow(dp, bounds.left, bounds.top, false);
+ SetPort(savePort);
}
-
-
-/* C Extensions */
-
-/*
- * Appends src to string dst of size dsize (unlike strncat, dsize is the
- * full size of dst, not space left). At most dsize-1 characters
- * will be copied. Always NUL terminates (unless dsize <= strlen(dst)).
- * Returns strlen(src) + MIN(dsize, strlen(initial dst)).
- * If retval >= dsize, truncation occurred.
- */
-size_t
-strlcat(char *dst, const char *src, size_t dsize)
-{
- const char *odst = dst;
- const char *osrc = src;
- size_t n = dsize;
- size_t dlen;
-
- /* Find the end of dst and adjust bytes left but don't go past end. */
- while (n-- != 0 && *dst != '\0')
- dst++;
- dlen = dst - odst;
- n = dsize - dlen;
-
- if (n-- == 0)
- return(dlen + strlen(src));
- while (*src != '\0') {
- if (n != 0) {
- *dst++ = *src;
- n--;
- }
- src++;
- }
- *dst = '\0';
-
- return(dlen + (src - osrc)); /* count does not include NUL */
-}
-
-/*
- * Copy string src to buffer dst of size dsize. At most dsize-1
- * chars will be copied. Always NUL terminates (unless dsize == 0).
- * Returns strlen(src); if retval >= dsize, truncation occurred.
- */
-size_t
-strlcpy(char *dst, const char *src, size_t dsize)
-{
- const char *osrc = src;
- size_t nleft = dsize;
-
- /* Copy as many bytes as will fit. */
- if (nleft != 0) {
- while (--nleft != 0) {
- if ((*dst++ = *src++) == '\0')
- break;
- }
- }
-
- /* Not enough room in dst, add NUL and traverse rest of src. */
- if (nleft == 0) {
- if (dsize != 0)
- *dst = '\0'; /* NUL-terminate dst */
- while (*src++)
- ;
- }
-
- return(src - osrc - 1); /* count does not include NUL */
-}
+#endif
--- wi-fi.h Thu Sep 21 10:20:21 2023
+++ wi-fi.h Fri Oct 20 22:48:49 2023
@@ -18,7 +18,11 @@
#define __WIFI_H__
#include <stdlib.h>
+#include "util.h"
+/* disable in production */
+#define DEBUG_LOGGING 1
+
#define MAIN_MENU_ID 1
#define MAIN_MENU_ABOUT_ID 1
#define MAIN_MENU_QUIT_ID 3
@@ -45,9 +49,6 @@
#define nitems(what) (sizeof((what)) / sizeof((what)[0]))
#define member_size(type, member) sizeof(((type *)0)->member)
-typedef Boolean bool;
-typedef signed long ssize_t;
-
typedef short SICN[16];
typedef SICN **SICNHandle;
@@ -87,31 +88,34 @@ struct wifi_join_request {
};
extern WindowPtr win;
+extern DCtlPtr dce;
extern short wifi_scsi_id;
enum {
WIFI_SCSI_ID_FINDING = -1,
WIFI_SCSI_ID_NONE = -2
};
+extern unsigned long wifi_scan_started;
extern struct wifi_network_entry wifi_cur_info;
extern struct wifi_network_entry wifi_scan_networks[10];
+extern short nwifi_scan_networks;
extern Cursor watch;
-void about(void);
+void wifi_about(void);
-size_t strlcat(char *dst, const char *src, size_t dsize);
-size_t strlcpy(char *dst, const char *src, size_t dsize);
-char * strndup(const char *str, size_t maxlen);
+#if DEBUG_LOGGING
+#define DEBUG_LOG(args) logger_printf args
+void logger_printf(const char *format, ...);
+#else
+#define DEBUG_LOG(args) ((void)0)
+#endif
WindowPtr create_window(short ctlrefnum);
void update_window(bool force);
void update_wifi_cur_info(void);
-void update_wifi_ssid_list(void);
+void update_wifi_ssid_list(bool update_networks);
void destroy_window(void);
void activate_window(bool activate);
-long OwnedResourceID(long n);
-void warn(char *format, ...);
-void CenterDialog(DialogPtr dp, bool titlebar);
void window_mousedown(Point p);
short scsi_find_wifi(void);
--- window.c Thu Sep 21 13:26:54 2023
+++ window.c Fri Oct 20 23:34:09 2023
@@ -28,6 +28,9 @@ SICNHandle signal_icons;
ControlHandle ssid_list;
MenuHandle ssid_menu;
Rect ssid_menu_rect;
+short nwifi_scan_networks = 0;
+struct wifi_network_entry wifi_menu_networks[nitems(wifi_scan_networks)] = { 0 };
+short nwifi_menu_networks = 0;
WindowPtr
create_window(short ctlrefnum)
@@ -112,6 +115,7 @@ update_window(bool force)
LineTo(ssid_menu_rect.right, ssid_menu_rect.bottom);
MoveTo(ssid_menu_rect.left + 15, 16);
TextFont(systemFont);
+ TextSize(0);
GetItem(ssid_menu, 1, &menuText);
DrawString(menuText);
@@ -160,70 +164,93 @@ update_wifi_cur_info(void)
scsi_wifi_info(wifi_scsi_id, &wifi_cur_info);
- if (memcmp(&old_info, &wifi_cur_info, sizeof(old_info)) != 0)
- update_window(true);
+ if (memcmp(&old_info, &wifi_cur_info, sizeof(old_info)) != 0) {
+ if (memcmp(&old_info.ssid, &wifi_cur_info.ssid,
+ sizeof(old_info.ssid)) == 0)
+ /* just updating RSSI */
+ update_window(true);
+ else
+ update_wifi_ssid_list(false);
+ }
}
void
-update_wifi_ssid_list(void)
+update_wifi_ssid_list(bool update_networks)
{
- struct wifi_network_entry tmpnets[10] = { 0 };
char ssid[64] = { 0 };
- short count, n, m, mitem;
+ short n, m, mitem;
if (wifi_scsi_id == WIFI_SCSI_ID_NONE)
return;
- count = scsi_wifi_scan_results(wifi_scsi_id, wifi_scan_networks,
- nitems(wifi_scan_networks));
-
- if (count == 0) {
- memcpy(&wifi_scan_networks, &wifi_cur_info,
- sizeof(wifi_cur_info));
- count = 1;
- } else {
- memcpy(&tmpnets[0], &wifi_cur_info, sizeof(wifi_cur_info));
+ if (update_networks) {
+ nwifi_scan_networks = scsi_wifi_scan_results(wifi_scsi_id,
+ wifi_scan_networks, nitems(wifi_scan_networks));
+ DEBUG_LOG(("scsi_wifi_scan_results: %d", nwifi_scan_networks));
- if (count > nitems(tmpnets))
- count = nitems(tmpnets);
+ if (nwifi_scan_networks == 0) {
+ memcpy(&wifi_scan_networks, &wifi_cur_info,
+ sizeof(wifi_cur_info));
+ nwifi_scan_networks = 1;
+ }
+ }
+
+ /* put the current network first, if any */
+ memcpy(&wifi_menu_networks[0], &wifi_cur_info,
+ sizeof(wifi_menu_networks[0]));
+
+ nwifi_menu_networks = nwifi_scan_networks;
+ if (nwifi_menu_networks > nitems(wifi_menu_networks)) {
+ nwifi_menu_networks = nitems(wifi_menu_networks);
+ DEBUG_LOG(("capping nets to %d", nwifi_menu_networks));
+ }
- for (n = 0, m = 1; n < count; n++) {
- if (strcmp(wifi_scan_networks[n].ssid,
- wifi_cur_info.ssid) == 0)
- continue;
-
- memcpy(&tmpnets[m++], &wifi_scan_networks[n],
- sizeof(tmpnets[0]));
+ /* add each additional network from the scan, excluding current */
+ for (n = 0, m = 1; n < nwifi_menu_networks; n++) {
+ if (strcmp(wifi_scan_networks[n].ssid,
+ wifi_cur_info.ssid) == 0) {
+ DEBUG_LOG(("skipping %s, is current",
+ wifi_scan_networks[n].ssid));
+ continue;
}
- memcpy(&wifi_scan_networks, &tmpnets,
- sizeof(wifi_scan_networks));
+ DEBUG_LOG(("net %d: %s", m, wifi_scan_networks[n].ssid));
+
+ memcpy(&wifi_menu_networks[m++], &wifi_scan_networks[n],
+ sizeof(wifi_menu_networks[0]));
}
- if (wifi_scan_networks[0].ssid[0] == '\0')
- strlcpy(wifi_scan_networks[0].ssid, NO_NETWORK_TEXT,
- sizeof(wifi_scan_networks[0].ssid));
+ nwifi_menu_networks = m;
+ if (wifi_menu_networks[0].ssid[0] == '\0')
+ strlcpy(wifi_menu_networks[0].ssid, NO_NETWORK_TEXT,
+ sizeof(wifi_menu_networks[0].ssid));
+
/* leave the first item and we'll set its text later */
while (CountMItems(ssid_menu) > 1)
DelMenuItem(ssid_menu, 2);
- for (n = 0, mitem = 1; n < count; n++) {
+ for (n = 0, mitem = 1; n < nwifi_menu_networks; n++) {
/*
* InsMenuItem supports meta chars in item text which can
* have side effects, so insert a blank item and then set its
* name with SetItem which does not suport meta chars.
*/
- strlcpy(ssid, wifi_scan_networks[n].ssid, sizeof(ssid));
+ strlcpy(ssid, wifi_menu_networks[n].ssid, sizeof(ssid));
CtoPstr(ssid);
if (n > 0)
- InsMenuItem(ssid_menu, ssid, mitem);
+ InsMenuItem(ssid_menu, "\pcarl", mitem);
SetItem(ssid_menu, mitem, ssid);
- CheckItem(ssid_menu, mitem,
- strcmp(wifi_scan_networks[n].ssid, wifi_cur_info.ssid) == 0);
+ if (wifi_cur_info.ssid[0] == '\0' && n == 0)
+ CheckItem(ssid_menu, mitem, true);
+ else
+ CheckItem(ssid_menu, mitem,
+ (strcmp(wifi_menu_networks[n].ssid,
+ wifi_cur_info.ssid) == 0));
+
mitem++;
}
@@ -262,7 +289,7 @@ destroy_window(void)
void
window_mousedown(Point p)
{
- Str255 pass;
+ char pass_storage[256];
char ssid[64];
Rect r, irect;
GrafPtr savePort;
@@ -295,7 +322,7 @@ window_mousedown(Point p)
mitems = CountMItems(ssid_menu);
selitem = 1;
for (n = 0; n < mitems; n++) {
- if (strcmp(wifi_scan_networks[n].ssid, wifi_cur_info.ssid) == 0) {
+ if (strcmp(wifi_menu_networks[n].ssid, wifi_cur_info.ssid) == 0) {
selitem = n + 1;
break;
}
@@ -306,38 +333,58 @@ window_mousedown(Point p)
DeleteMenu((*ssid_menu)->menuID);
if (hiword(new_net) != 0 && loword(new_net) != selitem) {
- net = &wifi_scan_networks[loword(new_net) - 1];
+ net = &wifi_menu_networks[loword(new_net) - 1];
strlcpy(ssid, net->ssid, sizeof(ssid));
CtoPstr(ssid);
- ParamText(ssid, "", "", "");
+ ParamText(ssid, "\p", "\p", "\p");
PtoCstr(ssid);
dg = GetNewDialog(OwnedResourceID(PASSWORD_DIALOG_ID), 0L,
(WindowPtr)-1L);
- CenterDialog(dg, false);
+ center_in_screen(((DialogPeek)dg)->window.port.portRect.right,
+ ((DialogPeek)dg)->window.port.portRect.bottom, false, &r);
+ MoveWindow(dg, r.left, r.top, false);
+
+ memset(pass_storage, 0, sizeof(pass_storage));
+ PasswordDialogFieldFilterSetup(PASSWORD_DIALOG_PASSWORD_FIELD_ID,
+ pass_storage, sizeof(pass_storage));
+
ShowWindow(dg);
+ SetPort(dg);
+
+ /* outline ok button */
+ GetDItem(dg, ok, &itype, &ihandle, &irect);
+ PenSize(3, 3);
+ InsetRect(&irect, -4, -4);
+ FrameRoundRect(&irect, 16, 16);
+ PenNormal();
+
for (;;) {
- ModalDialog(0, &hit);
+ ModalDialog(PasswordDialogFieldFilter, &hit);
if (hit == ok || hit == cancel)
break;
}
if (hit == ok) {
- GetDItem(dg, PASSWORD_DIALOG_PASSWORD_FIELD_ID, &itype,
- &ihandle, &irect);
- GetIText(ihandle, &pass);
- PtoCstr(pass);
+ //DEBUG_LOG(("pass is \"%s\"", pass_storage));
memset(&wjr, 0, sizeof(wjr));
strlcpy(wjr.ssid, ssid, sizeof(wjr.ssid));
- strlcpy(wjr.key, (char *)pass, sizeof(wjr.key));
+ strlcpy(wjr.key, pass_storage, sizeof(wjr.key));
+ PasswordDialogFieldFinish();
DisposDialog(dg);
scsi_wifi_join(wifi_scsi_id, &wjr);
- } else
+
+ /* force an update of the list */
+ scsi_wifi_info(wifi_scsi_id, &wifi_cur_info);
+ update_wifi_ssid_list(false);
+ } else {
+ PasswordDialogFieldFinish();
DisposDialog(dg);
+ }
}
SetPort(savePort);