| 
version 1.1, 2011/11/07 08:47:16
 | 
version 1.2, 2012/01/27 15:05:38
 | 
| 
 Line 1
 | 
 Line 1
 | 
 |  #include "global.h" | 
  #include "global.h" | 
 |   | 
   | 
 |   | 
   | 
| static int mqtt_Errno; | #pragma GCC visibility push(hidden) | 
| static char mqtt_Error[STRSIZ]; |   | 
 |   | 
   | 
 |   | 
  int mqtt_Errno; | 
 |   | 
  char mqtt_Error[STRSIZ]; | 
 |   | 
   | 
 |   | 
  #pragma GCC visibility pop | 
 |   | 
   | 
 |  // | 
  // | 
 |  // Error maintenance functions ... | 
  // Error maintenance functions ... | 
 |  // | 
  // | 
| 
 Line 36  mqtt_SetErr(int eno, char *estr, ...)
 | 
 Line 39  mqtt_SetErr(int eno, char *estr, ...)
 | 
 |          va_end(lst); | 
          va_end(lst); | 
 |  } | 
  } | 
 |   | 
   | 
 |   | 
  #pragma GCC visibility push(hidden) | 
 |   | 
  // _mqtt_readHEADER() read fixed header from MQTT message | 
 |   | 
  inline struct mqtthdr * | 
 |   | 
  _mqtt_readHEADER(mqtt_msg_t * __restrict buf, u_char cmd, int *bytes, int *len) | 
 |   | 
  { | 
 |   | 
          struct mqtthdr *hdr; | 
 |   | 
   | 
 |   | 
          if (!buf || !buf->msg_base || !buf->msg_len) | 
 |   | 
                  return NULL; | 
 |   | 
   | 
 |   | 
          hdr = (struct mqtthdr*) buf->msg_base; | 
 |   | 
          if (hdr->mqtt_msg.type != cmd) { | 
 |   | 
                  mqtt_SetErr(EINVAL, "Error:: wrong command #%d should be %d",  | 
 |   | 
                                  hdr->mqtt_msg.type, cmd); | 
 |   | 
                  return NULL; | 
 |   | 
          } | 
 |   | 
   | 
 |   | 
          *len = mqtt_decodeLen(hdr->mqtt_len, bytes); | 
 |   | 
          return hdr; | 
 |   | 
  } | 
 |   | 
  #pragma GCC visibility pop | 
 |   | 
   | 
 |  // ---------------------------------------------------------- | 
  // ---------------------------------------------------------- | 
 |   | 
   | 
 |   | 
  /* | 
 |   | 
   * mqtt_msgFree() Free MQTT message | 
 |   | 
   * | 
 |   | 
   * @msg = Message buffer | 
 |   | 
   * @all = !=0 Destroy entire message, if MQTT Message allocated with mqtt_msgAlloc() | 
 |   | 
   * return: none | 
 |   | 
   */ | 
 |   | 
  inline void | 
 |   | 
  mqtt_msgFree(mqtt_msg_t ** __restrict msg, int all) | 
 |   | 
  { | 
 |   | 
          if (msg && *msg) { | 
 |   | 
                  if ((*msg)->msg_base) { | 
 |   | 
                          free((*msg)->msg_base); | 
 |   | 
                          (*msg)->msg_base = NULL; | 
 |   | 
                  } | 
 |   | 
                  if (all) { | 
 |   | 
                          free(*msg); | 
 |   | 
                          *msg = NULL; | 
 |   | 
                  } else | 
 |   | 
                          (*msg)->msg_len ^= (*msg)->msg_len; | 
 |   | 
          } | 
 |   | 
  } | 
 |   | 
   | 
 |   | 
  /* | 
 |   | 
   * mqtt_msgAlloc() Allocate memory for MQTT Message | 
 |   | 
   * | 
 |   | 
   * @len = >0 Allocate buffer with length | 
 |   | 
   * return: NULL error or Message, after use must call mqtt_msgFree() with all!=0 | 
 |   | 
   */ | 
 |   | 
  inline mqtt_msg_t * | 
 |   | 
  mqtt_msgAlloc(u_short len) | 
 |   | 
  { | 
 |   | 
          mqtt_msg_t *m = NULL; | 
 |   | 
   | 
 |   | 
          m = malloc(sizeof(mqtt_msg_t)); | 
 |   | 
          if (!m) { | 
 |   | 
                  LOGERR; | 
 |   | 
                  return NULL; | 
 |   | 
          } else | 
 |   | 
                  memset(m, 0, sizeof(mqtt_msg_t)); | 
 |   | 
   | 
 |   | 
          if (len) { | 
 |   | 
                  m->msg_len = len; | 
 |   | 
                  m->msg_base = malloc(m->msg_len); | 
 |   | 
                  if (!m->msg_base) { | 
 |   | 
                          LOGERR; | 
 |   | 
                          free(m); | 
 |   | 
                          return NULL; | 
 |   | 
                  } else | 
 |   | 
                          memset(m->msg_base, 0, m->msg_len); | 
 |   | 
          } | 
 |   | 
   | 
 |   | 
          return m; | 
 |   | 
  } | 
 |   | 
   | 
 |   | 
  /* | 
 |   | 
   * mqtt_msgRealloc() Reallocate MQTT message buffer | 
 |   | 
   * | 
 |   | 
   * @msg = MQTT message | 
 |   | 
   * @len = new length | 
 |   | 
   * return: -1 error or >-1 old buffer length | 
 |   | 
   */ | 
 |   | 
  inline int | 
 |   | 
  mqtt_msgRealloc(mqtt_msg_t * __restrict msg, u_short len) | 
 |   | 
  { | 
 |   | 
          void *p = NULL; | 
 |   | 
          int ret = 0; | 
 |   | 
   | 
 |   | 
          if (!msg) | 
 |   | 
                  return -1; | 
 |   | 
   | 
 |   | 
          if (len == msg->msg_len) | 
 |   | 
                  return len; | 
 |   | 
   | 
 |   | 
          p = realloc(msg->msg_base, len); | 
 |   | 
          if (!p) { | 
 |   | 
                  LOGERR; | 
 |   | 
                  return -1; | 
 |   | 
          } | 
 |   | 
   | 
 |   | 
          ret = msg->msg_len; | 
 |   | 
          msg->msg_len = len; | 
 |   | 
          msg->msg_base = p; | 
 |   | 
   | 
 |   | 
          return ret; | 
 |   | 
  } | 
 |   | 
   | 
 |   | 
  /* | 
 |   | 
   * mqtt_encodeLen() Encode number to MQTT length field | 
 |   | 
   * | 
 |   | 
   * @num = number for encode | 
 |   | 
   * return: -1 error or >-1 length | 
 |   | 
   */ | 
 |   | 
  inline u_int | 
 |   | 
  mqtt_encodeLen(u_int num) | 
 |   | 
  { | 
 |   | 
          register u_int dig, i; | 
 |   | 
          u_int ret = 0; | 
 |   | 
   | 
 |   | 
          if (num > 268435455) | 
 |   | 
                  return (u_int) -1; | 
 |   | 
   | 
 |   | 
          for (i = 0; i < sizeof ret && num > 0; i++) { | 
 |   | 
                  dig = num % 0x80; | 
 |   | 
                  num /= 0x80; | 
 |   | 
                  if (num > 0) | 
 |   | 
                          dig |= 0x80; | 
 |   | 
   | 
 |   | 
                  *((u_char*) &ret + i) = (u_char) dig; | 
 |   | 
          } | 
 |   | 
   | 
 |   | 
          return ret; | 
 |   | 
  } | 
 |   | 
   | 
 |   | 
  /* | 
 |   | 
   * mqtt_decodeLen() Decode length from MQTT packet | 
 |   | 
   * | 
 |   | 
   * @len = length from MQTT header | 
 |   | 
   * @n = sizeof bytes, if !=NULL | 
 |   | 
   * return: -1 error, >-1 length of message | 
 |   | 
   */ | 
 |   | 
  inline u_int | 
 |   | 
  mqtt_decodeLen(void * __restrict len, int * __restrict n) | 
 |   | 
  { | 
 |   | 
          register u_int i, dig, mul; | 
 |   | 
          u_int ret = 0; | 
 |   | 
          u_char *p = (u_char*) len; | 
 |   | 
   | 
 |   | 
          if (!len) | 
 |   | 
                  return (u_int) -1; | 
 |   | 
   | 
 |   | 
          for (mul = 1, i = 0; i < sizeof ret; i++, mul *= 0x80) { | 
 |   | 
                  dig = p[i]; | 
 |   | 
                  ret += (dig & 0x7f) * mul; | 
 |   | 
   | 
 |   | 
                  if (!(dig & 0x80)) | 
 |   | 
                          break; | 
 |   | 
          } | 
 |   | 
   | 
 |   | 
          if (n) | 
 |   | 
                  *n = (char) (i & 0x7f) + 1; | 
 |   | 
          return ret; | 
 |   | 
  } | 
 |   | 
   | 
 |   | 
  /* | 
 |   | 
   * mqtt_sizeLen Return sizeof len field | 
 |   | 
   * | 
 |   | 
   * @len = length | 
 |   | 
   * return: -1 error, >-1 sizeof len in bytes | 
 |   | 
   */ | 
 |   | 
  inline char | 
 |   | 
  mqtt_sizeLen(u_int len) | 
 |   | 
  { | 
 |   | 
          register char i; | 
 |   | 
          u_char *p = (u_char*) &len; | 
 |   | 
   | 
 |   | 
          if (len > 0xffffff7f) | 
 |   | 
                  return -1; | 
 |   | 
   | 
 |   | 
          for (i = 0; i < sizeof len; i++) | 
 |   | 
                  if (!(*(p + i) & 0x80)) | 
 |   | 
                          break; | 
 |   | 
   | 
 |   | 
          return ++i; | 
 |   | 
  } | 
 |   | 
   | 
 |   | 
  /* | 
 |   | 
   * mqtt_str2sub Create MQTT subscribe variable from string(s) | 
 |   | 
   * | 
 |   | 
   * @csStr = strings | 
 |   | 
   * @strnum = number of strings elements | 
 |   | 
   * @qoses = QoS elements applied to subscribe variable,  | 
 |   | 
   *              count of elements must be equal with csStr elements | 
 |   | 
   * return: NULL error or != subscribe variables array, must be free after use with mqtt_freeSub() | 
 |   | 
   */ | 
 |   | 
  inline mqtt_subscr_t * | 
 |   | 
  mqtt_str2sub(const char **csStr, u_short strnum, u_char *qoses) | 
 |   | 
  { | 
 |   | 
          mqtt_subscr_t *v; | 
 |   | 
          register int i, items; | 
 |   | 
          const char **strs; | 
 |   | 
   | 
 |   | 
          if (!csStr) | 
 |   | 
                  return NULL; | 
 |   | 
          for (items = 0, strs = csStr; *strs; items++, strs++) | 
 |   | 
                  if (strnum && items >= strnum) { | 
 |   | 
                          items = strnum; | 
 |   | 
                          break; | 
 |   | 
                  } | 
 |   | 
   | 
 |   | 
          if (!(v = malloc((items + 1) * sizeof(mqtt_subscr_t)))) { | 
 |   | 
                  LOGERR; | 
 |   | 
                  return NULL; | 
 |   | 
          } else | 
 |   | 
                  memset(v, 0, (items + 1) * sizeof(mqtt_subscr_t)); | 
 |   | 
   | 
 |   | 
          for (i = 0; i < items; i++) { | 
 |   | 
                  v[i].sub_topic._size = strlen(csStr[i]); | 
 |   | 
                  v[i].sub_topic._base = (u_char*) strdup(csStr[i]); | 
 |   | 
                  if (qoses && qoses[i] < MQTT_QOS_RESERVED) | 
 |   | 
                          v[i].sub_ret = qoses[i]; | 
 |   | 
          } | 
 |   | 
   | 
 |   | 
          return v; | 
 |   | 
  } | 
 |   | 
   | 
 |   | 
  /* | 
 |   | 
   * mqtt_subFree() Free array from subscribe variables | 
 |   | 
   * | 
 |   | 
   * @subs = Subscribe variables | 
 |   | 
   * return: none | 
 |   | 
   */ | 
 |   | 
  inline void | 
 |   | 
  mqtt_subFree(mqtt_subscr_t ** __restrict subs) | 
 |   | 
  { | 
 |   | 
          mqtt_subscr_t *v; | 
 |   | 
   | 
 |   | 
          if (!subs) | 
 |   | 
                  return; | 
 |   | 
   | 
 |   | 
          for (v = *subs; v->sub_topic._base; v++) { | 
 |   | 
                  free(v->sub_topic._base); | 
 |   | 
                  v->sub_topic._base = NULL; | 
 |   | 
                  v->sub_topic._size = 0; | 
 |   | 
   | 
 |   | 
                  if (v->sub_value._base) { | 
 |   | 
                          free(v->sub_value._base); | 
 |   | 
                          v->sub_value._base = NULL; | 
 |   | 
                          v->sub_value._size = 0; | 
 |   | 
                  } | 
 |   | 
          } | 
 |   | 
   | 
 |   | 
          free(*subs); | 
 |   | 
          *subs = NULL; | 
 |   | 
  } | 
 |   | 
   | 
 |   | 
  /* | 
 |   | 
   * mqtt_subAlloc() Create array from subscribe variables | 
 |   | 
   * | 
 |   | 
   * @num = Number of elements | 
 |   | 
   * return: NULL error or subscribe array, after use must call mqtt_subFree() | 
 |   | 
   */ | 
 |   | 
  inline mqtt_subscr_t * | 
 |   | 
  mqtt_subAlloc(u_short num) | 
 |   | 
  { | 
 |   | 
          mqtt_subscr_t *s = NULL; | 
 |   | 
   | 
 |   | 
          s = malloc((num + 1) * sizeof(mqtt_subscr_t)); | 
 |   | 
          if (!s) { | 
 |   | 
                  LOGERR; | 
 |   | 
                  return NULL; | 
 |   | 
          } else | 
 |   | 
                  memset(s, 0, (num + 1) * sizeof(mqtt_subscr_t)); | 
 |   | 
   | 
 |   | 
          return s; | 
 |   | 
  } | 
 |   | 
   | 
 |   | 
  /* | 
 |   | 
   * mqtt_subRealloc() Reallocate array from subscribe variables | 
 |   | 
   * | 
 |   | 
   * @subs = Subscribe array | 
 |   | 
   * @num = Number of elements | 
 |   | 
   * return: NULL error or subscribe array, after use must call mqtt_subFree() | 
 |   | 
   */ | 
 |   | 
  inline mqtt_subscr_t * | 
 |   | 
  mqtt_subRealloc(mqtt_subscr_t * __restrict subs, u_short num) | 
 |   | 
  { | 
 |   | 
          mqtt_subscr_t *s = NULL; | 
 |   | 
   | 
 |   | 
          s = realloc(subs, (num + 1) * sizeof(mqtt_subscr_t)); | 
 |   | 
          if (!s) { | 
 |   | 
                  LOGERR; | 
 |   | 
                  return NULL; | 
 |   | 
          } | 
 |   | 
   | 
 |   | 
          return s; | 
 |   | 
  } |