/* * _pygsmd.c, python bindings for libgsmd * Written by Sudharshan "Sup3rkiddo" S <sudharsh@gmail.com> * (C)2006-2007 All Rights Reserved, * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */#include "pygsmd.h"PyObject *GSMDError;PyObject *net;int FLAG;pthread_t evt_loop;pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/* Static protoype of pygsmd main loop to read from the gsmd socket */static int pygsmd_main_loop(struct lgsm_handle *);static int net_msghandler(struct lgsm_handle *lgsmh, struct gsmd_msg_hdr *gmh) { int sigq, ber_rate; const struct gsmd_signal_quality *sq = (struct gsmd_signal_quality *) ((void *)gmh + sizeof(*gmh)); const char *oper = (char *)gmh + sizeof(*gmh); switch(gmh->msg_subtype) { case GSMD_NETWORK_SIGQ_GET: /* Return a tuple of signal quality (in dBm) and Bit Error rate */ sigq = (sq->rssi * 2)-113; ber_rate = sq->ber; net = Py_BuildValue("(ii)", sigq==99 ? 0:sigq, ber_rate==99 ? 0:ber_rate); break; case GSMD_NETWORK_OPER_GET: net = Py_BuildValue("z", oper); break; default: return -EINVAL; } pthread_mutex_unlock(&mutex);}static int pt_msghandler(struct lgsm_handle *lgsmh, struct gsmd_msg_hdr *gmh) { /* TBD */ return 0;}static int voice_msghandler(struct lgsm_handle *lgsmh, struct gsmd_msg_hdr *gmh) { /* TBD */ return 0;}struct lgsm_handle *pygsmd_init(int msg_type) { struct lgsm_handle *handle = NULL; GSMDError = PyErr_NewException("pygsmd.error", NULL, NULL); Py_INCREF(GSMDError); handle = lgsm_init(LGSMD_DEVICE_GSMD); if(handle) { switch(msg_type) { case GSMD_MSG_PASSTHROUGH: lgsm_register_handler(handle, GSMD_MSG_PASSTHROUGH, &pt_msghandler); break; case GSMD_MSG_NETWORK: lgsm_register_handler(handle, GSMD_MSG_NETWORK, &net_msghandler); break; case GSMD_MSG_VOICECALL: lgsm_register_handler(handle, GSMD_MSG_VOICECALL, &voice_msghandler); break; default: return NULL; } /* since we are initialising the handles in all the modules, we set a flag to prevent * duplicate threads from spawning */ if(FLAG==0) { pthread_create(&evt_loop, NULL, (void *)&pygsmd_main_loop, (void *)handle); FLAG = 1; } } else { PyErr_SetString(GSMDError, "Couldn't initialise the handle, Check if GSMD is running"); return NULL; } return handle;}static int pygsmd_main_loop(struct lgsm_handle *handle) { int gsm_fd; int rc=0; char buf[1025]; fd_set readset; fcntl(lgsm_fd(handle), F_SETFD, O_NONBLOCK); FD_ZERO(&readset); while(1) { pthread_mutex_lock(&mutex); gsm_fd = lgsm_fd(handle); FD_SET(gsm_fd, &readset); rc = select(gsm_fd+1, &readset, NULL, NULL, NULL); if(FD_ISSET(gsm_fd, &readset)) { /* Knock knock. we have something on the gsmd socket. handling it */ rc = read(gsm_fd, buf, sizeof(buf)); if(rc<=0) { PyErr_SetString(GSMDError, "Error reading from gsmd socket"); return -1; } rc = lgsm_handle_packet(handle, buf, rc); } } return 0;}