source: trunk/LocationDo/SCNetworkReachabilitymodule.c@ 236

Last change on this file since 236 was 205, checked in by Nicholas Riley, 17 years ago

LocationDo.py: Add a bunch of TODOs, and some more locations and
actions.

action.py: Add a TODO.

SCNetworkReachabilitymodule.c: Add a TODO.

File size: 2.7 KB
Line 
1#include "Python.h"
2
3#include <SystemConfiguration/SystemConfiguration.h>
4
5#define SCNR_REACHABLE "SCNetworkIsReachable"
6static CFStringRef SCNR_Reachable = CFSTR(SCNR_REACHABLE);
7static SCNetworkReachabilityContext SCNR_Context = {0, NULL, NULL, NULL, NULL};
8
9static void
10SCNR_callback(SCNetworkReachabilityRef target,
11 SCNetworkConnectionFlags flags, void *tagString);
12
13static Boolean
14SCNR_reachable(SCNetworkConnectionFlags flags) {
15 /* not reachable if it requires a non-automatic connection */
16 return ((flags & kSCNetworkFlagsReachable) &&
17 (!(flags & kSCNetworkFlagsConnectionRequired) ||
18 (flags & kSCNetworkFlagsConnectionAutomatic)));
19}
20
21/* XXX should have a way to cancel (e.g. on location detach) */
22
23static void
24SCNR_schedule(CFStringRef tagString,
25 SCNetworkReachabilityRef target) {
26 SCNR_Context.info = (void *)tagString;
27 SCNetworkReachabilitySetCallback(target, SCNR_callback, &SCNR_Context);
28 SCNetworkReachabilityScheduleWithRunLoop(target,
29 CFRunLoopGetCurrent(),
30 kCFRunLoopDefaultMode);
31}
32
33static void
34SCNR_callback(SCNetworkReachabilityRef target,
35 SCNetworkConnectionFlags flags, void *tagString) {
36 if (SCNR_reachable(flags)) {
37 CFNotificationCenterPostNotification(CFNotificationCenterGetLocalCenter(),
38 SCNR_Reachable, tagString, NULL, false);
39 CFRelease((CFStringRef)tagString);
40 } else {
41 SCNR_schedule(tagString, target);
42 }
43}
44
45static PyObject *
46SCNR_notify_when_reachable(PyObject *self, PyObject *args) {
47 const char *hostname;
48 const char *tag;
49 if (!PyArg_ParseTuple(args, "ss", &hostname, &tag))
50 return NULL;
51
52 SCNetworkConnectionFlags flags;
53 if (SCNetworkCheckReachabilityByName(hostname, &flags) &&
54 SCNR_reachable(flags))
55 return PyBool_FromLong(0);
56
57 SCNetworkReachabilityRef target =
58 SCNetworkReachabilityCreateWithName(NULL, hostname);
59 CFStringRef tagString =
60 CFStringCreateWithCString(NULL, tag, kCFStringEncodingUTF8);
61
62 SCNR_schedule(tagString, target);
63
64 return PyBool_FromLong(1);
65}
66
67
68static PyMethodDef SCNetworkReachabilitymodule_methods[] = {
69 {"notify_when_reachable", SCNR_notify_when_reachable, METH_VARARGS,
70 "notify_when_reachable(hostname, tag) -> bool\n\n"
71 "Deliver the SCNetworkIsReachable runloop notification with object tag\n"
72 "when the host becomes reachable, or return false if it's currently\n"
73 "reachable."},
74 {NULL, NULL, 0, NULL}
75};
76
77PyMODINIT_FUNC
78initSCNetworkReachability(void) {
79 PyObject *module = Py_InitModule("SCNetworkReachability",
80 SCNetworkReachabilitymodule_methods);
81 PyObject *dict = PyModule_GetDict(module);
82 PyObject *reachable = PyString_FromString(SCNR_REACHABLE);
83 PyDict_SetItemString(dict, SCNR_REACHABLE, reachable);
84 Py_DECREF(reachable);
85}
Note: See TracBrowser for help on using the repository browser.