source: trunk/LocationDo/SCNetworkReachabilitymodule.c @ 196

Last change on this file since 196 was 196, checked in by Nicholas Riley, 14 years ago

LocationDo?

File size: 2.6 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
21static void
22SCNR_schedule(CFStringRef tagString,
23              SCNetworkReachabilityRef target) {
24  SCNR_Context.info = (void *)tagString;
25  SCNetworkReachabilitySetCallback(target, SCNR_callback, &SCNR_Context);
26  SCNetworkReachabilityScheduleWithRunLoop(target,
27                                           CFRunLoopGetCurrent(),
28                                           kCFRunLoopDefaultMode);
29}
30
31static void
32SCNR_callback(SCNetworkReachabilityRef target,
33              SCNetworkConnectionFlags flags, void *tagString) {
34  if (SCNR_reachable(flags)) {
35    CFNotificationCenterPostNotification(CFNotificationCenterGetLocalCenter(),
36                                         SCNR_Reachable, tagString, NULL, false);
37    CFRelease((CFStringRef)tagString);
38  } else {
39    SCNR_schedule(tagString, target);
40  }
41}
42
43static PyObject *
44SCNR_notify_when_reachable(PyObject *self, PyObject *args) {
45  const char *hostname;
46  const char *tag;
47  if (!PyArg_ParseTuple(args, "ss", &hostname, &tag))
48    return NULL;
49
50  SCNetworkConnectionFlags flags;
51  if (SCNetworkCheckReachabilityByName(hostname, &flags) &&
52      SCNR_reachable(flags))
53    return PyBool_FromLong(0);
54
55  SCNetworkReachabilityRef target =
56    SCNetworkReachabilityCreateWithName(NULL, hostname);
57  CFStringRef tagString =
58    CFStringCreateWithCString(NULL, tag, kCFStringEncodingUTF8);
59
60  SCNR_schedule(tagString, target);
61
62  return PyBool_FromLong(1);
63}
64
65
66static PyMethodDef SCNetworkReachabilitymodule_methods[] = {
67  {"notify_when_reachable", SCNR_notify_when_reachable, METH_VARARGS,
68   "notify_when_reachable(hostname, tag) -> bool\n\n"
69   "Deliver the SCNetworkIsReachable runloop notification with object tag\n"
70   "when the host becomes reachable, or return false if it's currently\n"
71   "reachable."},
72  {NULL, NULL, 0, NULL}
73};
74
75PyMODINIT_FUNC
76initSCNetworkReachability(void) {
77  PyObject *module = Py_InitModule("SCNetworkReachability",
78                                   SCNetworkReachabilitymodule_methods);
79  PyObject *dict = PyModule_GetDict(module);
80  PyObject *reachable = PyString_FromString(SCNR_REACHABLE);
81  PyDict_SetItemString(dict, SCNR_REACHABLE, reachable);
82  Py_DECREF(reachable);
83}
Note: See TracBrowser for help on using the repository browser.