Skip to content
api.c 70.3 KiB
Newer Older
Franz's avatar
Franz committed
/*
  libxbee - a C library to aid the use of Digi's Series 1 XBee modules
            running in API mode (AP=2).

  Copyright (C) 2009  Attie Grande (attie@attie.co.uk)

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program 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 General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
const char *SVN_REV = "$Id: api.c 508 2011-06-12 23:22:34Z attie@attie.co.uk $";
char svn_rev[128] = "\0";

#include "api.h"

const char *xbee_svn_version(void) {
  if (svn_rev[0] == '\0') {
    char *t;
    sprintf(svn_rev,"r%s",&SVN_REV[11]);
    t = strrchr(svn_rev,' ');
    if (t) {
      t[0] = '\0';
    }
  }
  return svn_rev;
}

const char *xbee_build_info(void) {
  return "Built on " __DATE__ " @ " __TIME__ " for " HOST_OS;
}

/* ################################################################# */
/* ### Memory Handling ############################################# */
/* ################################################################# */

/* malloc wrapper function */
static void *Xmalloc2(xbee_hnd xbee, size_t size) {
  void *t;
  t = malloc(size);
  if (!t) {
    /* uhoh... thats pretty bad... */
    xbee_perror("libxbee:malloc()");
    exit(1);
  }
  return t;
}

/* calloc wrapper function */
static void *Xcalloc2(xbee_hnd xbee, size_t size) {
  void *t;
  t = calloc(1, size);
  if (!t) {
    /* uhoh... thats pretty bad... */
    xbee_perror("libxbee:calloc()");
    exit(1);
  }
  return t;
}

/* realloc wrapper function */
static void *Xrealloc2(xbee_hnd xbee, void *ptr, size_t size) {
  void *t;
  t = realloc(ptr,size);
  if (!t) {
    /* uhoh... thats pretty bad... */
    fprintf(stderr,"libxbee:realloc(): Returned NULL\n");
    exit(1);
  }
  return t;
}

/* free wrapper function (uses the Xfree macro and sets the pointer to NULL after freeing it) */
static void Xfree2(void **ptr) {
  if (!*ptr) return;
  free(*ptr);
  *ptr = NULL;
}

/* ################################################################# */
/* ### Helper Functions ############################################ */
/* ################################################################# */

/* #################################################################
   returns 1 if the packet has data for the digital input else 0 */
int xbee_hasdigital(xbee_pkt *pkt, int sample, int input) {
  int mask = 0x0001;
  if (input < 0 || input > 7) return 0;
  if (sample >= pkt->samples) return 0;

  mask <<= input;
  return !!(pkt->IOdata[sample].IOmask & mask);
}

/* #################################################################
   returns 1 if the digital input is high else 0 (or 0 if no digital data present) */
int xbee_getdigital(xbee_pkt *pkt, int sample, int input) {
  int mask = 0x0001;
  if (!xbee_hasdigital(pkt,sample,input)) return 0;

  mask <<= input;
  return !!(pkt->IOdata[sample].IOdigital & mask);
}

/* #################################################################
   returns 1 if the packet has data for the analog input else 0 */
int xbee_hasanalog(xbee_pkt *pkt, int sample, int input) {
  int mask = 0x0200;
  if (input < 0 || input > 5) return 0;
  if (sample >= pkt->samples) return 0;

  mask <<= input;
  return !!(pkt->IOdata[sample].IOmask & mask);
}

/* #################################################################
   returns analog input as a voltage if vRef is non-zero, else raw value (or 0 if no analog data present) */
double xbee_getanalog(xbee_pkt *pkt, int sample, int input, double Vref) {
  if (!xbee_hasanalog(pkt,sample,input)) return 0;

  if (Vref) return (Vref / 1023) * pkt->IOdata[sample].IOanalog[input];
  return pkt->IOdata[sample].IOanalog[input];
}

/* ################################################################# */
/* ### XBee Functions ############################################## */
/* ################################################################# */

static void xbee_logf(xbee_hnd xbee, const char *logformat, const char *file,
                      const int line, const char *function, char *format, ...) {
  char buf[128];
  va_list ap;
  if (!xbee) return;
  if (!xbee->log) return;
  va_start(ap,format);
  vsnprintf(buf,127,format,ap);
  va_end(ap);
  fprintf(xbee->log,logformat,file,line,function,buf);
}
void xbee_logitf(char *format, ...) {
  char buf[128];
  va_list ap;
  va_start(ap,format);
  vsnprintf(buf,127,format,ap);
  va_end(ap);
  xbee_logit(buf);
}
void _xbee_logitf(xbee_hnd xbee, char *format, ...) {
  char buf[128];
  va_list ap;
  va_start(ap,format);
  vsnprintf(buf,127,format,ap);
  va_end(ap);
  _xbee_logit(xbee, buf);
}
void xbee_logit(char *str) {
  _xbee_logit(default_xbee, str);
}
void _xbee_logit(xbee_hnd xbee, char *str) {
  if (!xbee) return;
  if (!xbee->log) return;
  xbee_mutex_lock(xbee->logmutex);
  fprintf(xbee->log,LOG_FORMAT"\n",__FILE__,__LINE__,__FUNCTION__,str);
  xbee_mutex_unlock(xbee->logmutex);
}

/* #################################################################
   xbee_sendAT - INTERNAL
   allows for an at command to be send, and the reply to be captured */
static int xbee_sendAT(xbee_hnd xbee, char *command, char *retBuf, int retBuflen) {
  return xbee_sendATdelay(xbee, 0, command, retBuf, retBuflen);
}
static int xbee_sendATdelay(xbee_hnd xbee, int guardTime, char *command, char *retBuf, int retBuflen) {
  struct timeval to;

  int ret;
  int bufi = 0;

  /* if there is a guardTime given, then use it and a bit more */
  if (guardTime) usleep(guardTime * 1200);

  /* get rid of any pre-command sludge... */
  memset(&to, 0, sizeof(to));
  ret = xbee_select(xbee,&to);
  if (ret > 0) {
    char t[128];
    while (xbee_read(xbee,t,127));
  }

  /* send the requested command */
  xbee_log("sendATdelay: Sending '%s'", command);
  xbee_write(xbee,command, strlen(command));
Loading
Loading full blame...