Advertisement
Guest User

Untitled

a guest
Mar 27th, 2015
227
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.94 KB | None | 0 0
  1. /* low-level protocol routines */
  2.  
  3. /* TaniDVR
  4.  * Copyright (c) 2011-2015 Daniel Mealha Cabrita
  5.  *
  6.  * This program is free software: you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation, either version 3 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  */
  19.  
  20. #include <strings.h>
  21. #include <stdint.h>
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <poll.h>
  25. #include "llprotocol.h"
  26. #include "network.h"
  27. #include "bintools.h"
  28.  
  29. int llp_open (t_llp_connection *llp_connection, const char *hostname, unsigned short int port, unsigned int timeout_us)
  30. {
  31.     return (net_open (&(llp_connection->net_connection), hostname, port, timeout_us));
  32. }
  33.  
  34. int llp_get_header (t_llp_connection *llp_connection, t_ll_header *ll_header)
  35. {
  36.     llp_init_header (ll_header);    /* zero frame, just in case if partial fread() */
  37.  
  38.     if (fread (ll_header->raw, 1, LLP_HEADER_SIZE, llp_connection->net_connection.net_sockrfp) != LLP_HEADER_SIZE) {
  39.         return 1;
  40.     }
  41.  
  42.     ll_header->extlen = BT_LM2NV_U32((ll_header->raw) + 4);
  43.  
  44.     return 0;
  45. }
  46.  
  47. /* TODO: implement this */
  48. int llp_get_extdata (t_llp_connection *llp_connection, t_ll_header *ll_header)
  49. {
  50. //  if (ll_header->extdata == NULL)
  51. //      return 1;
  52. //  if (fread (ll_header->extdata, 1, ll_header->extlen, llp_connection->net_connection.net_sockrfp) != ll_header->extlen)
  53. //      return 1;
  54.  
  55.     return 0;
  56. }
  57.  
  58. /* returns the length of data, or 0 if there's none, or a negative value (error). */
  59. int llp_get_extdata_sbuff (t_llp_connection *llp_connection, t_ll_header *ll_header, uint8_t *buf, uint32_t buflen)
  60. {
  61.     if (ll_header->extlen == 0)
  62.         return 0;
  63.  
  64.     if (buflen < ll_header->extlen)
  65.         return -2; /* not enough buffer */
  66.  
  67.     if (fread (buf, 1, ll_header->extlen, llp_connection->net_connection.net_sockrfp) != ll_header->extlen)
  68.         return -1; /* read failed */
  69.  
  70.     return ll_header->extlen;
  71. }
  72.  
  73.  
  74.  
  75. #define DISCARD_CHUNK_SIZE 65536
  76. /* ll_header must contain a valid header */
  77. /* returns: ==0 ok, !=0 error */
  78. int llp_get_discard_extdata (t_llp_connection *llp_connection, t_ll_header *ll_header)
  79. {
  80.     uint32_t rem_extlen = ll_header->extlen;
  81.     uint8_t discard[DISCARD_CHUNK_SIZE];
  82.     uint32_t to_read;
  83.  
  84.     if (rem_extlen == 0)
  85.         return 0;
  86.  
  87.     while (rem_extlen != 0) {
  88.         if (rem_extlen > DISCARD_CHUNK_SIZE) {
  89.             to_read = DISCARD_CHUNK_SIZE;
  90.         } else {
  91.             to_read = rem_extlen;
  92.         }
  93.  
  94.         if (fread (discard, 1, to_read, llp_connection->net_connection.net_sockrfp) != to_read)
  95.             return 2;
  96.         rem_extlen -= to_read;
  97.     }
  98.  
  99.     return 0;
  100. }
  101.  
  102. void llp_init_header (t_ll_header *ll_header)
  103. {
  104.     bzero (ll_header, sizeof (t_ll_header));
  105. }
  106.  
  107. int llp_send_header (t_llp_connection *llp_connection, t_ll_header *ll_header)
  108. {
  109.     BT_NV2LM_U32((ll_header->raw) + 4,(ll_header->extlen))
  110.     if (fwrite (ll_header->raw, 1, LLP_HEADER_SIZE, llp_connection->net_connection.net_sockwfp) != LLP_HEADER_SIZE)
  111.         return 1;
  112.     fflush (llp_connection->net_connection.net_sockwfp);
  113.  
  114.     return 0;
  115. }
  116.  
  117. /* send an innocuous request.
  118.    this is used to detect lack of response from a previous request,
  119.    otherwise the waiting would hog fread() until timeout */
  120. int llp_send_nop (t_llp_connection *llp_connection)
  121. {
  122.     t_ll_header ll_header;
  123.  
  124.     llp_init_header (&ll_header);
  125.     ll_header.llp_hd_cmd = LLP_HD_NOP_REQ;
  126.  
  127.     return llp_send_header (llp_connection, &ll_header);
  128. }
  129.  
  130. int llp_send_extdata (t_llp_connection *llp_connection, uint8_t *payload, uint32_t len)
  131. {
  132.     if (fwrite (payload, 1, len, llp_connection->net_connection.net_sockwfp) != len)
  133.         return 1;
  134.     fflush (llp_connection->net_connection.net_sockwfp);
  135.     return 0;
  136. }
  137.  
  138. void llp_close (t_llp_connection *llp_connection)
  139. {
  140.     net_close (&(llp_connection->net_connection));
  141. }
  142.  
  143. /* returns >0 if there's pending data to be readen, ==0 otherwise, <0 if error */
  144. int llp_check_incoming_data (t_llp_connection *llp_connection)
  145. {
  146.     struct pollfd sock_pollfd;
  147.  
  148.     sock_pollfd.fd = llp_connection->net_connection.net_sockfd;
  149.     sock_pollfd.events = POLLIN;
  150.     return (poll(&sock_pollfd, 1, 0));
  151. }
  152.  
  153. /* wait for one or more connections to have incoming data, or until wait_timeout (ms) is reached.
  154.    returns: >0 incoming data, ==0 no data, <0 error */
  155. int llp_wait_for_incoming_data (t_llp_connection **llp_connection, int n_llp_connections, int wait_timeout)
  156. {
  157.     struct pollfd sock_pollfd[n_llp_connections];
  158.     int i;
  159.  
  160.     for (i = 0; i < n_llp_connections; i++) {
  161.         sock_pollfd[i].fd = llp_connection[i]->net_connection.net_sockfd;
  162.         sock_pollfd[i].events = POLLIN;
  163.     }
  164.     return (poll(&sock_pollfd[0], n_llp_connections, wait_timeout));
  165. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement