Patrick Barrett / libexositecoap
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers exosite_pal.c Source File

exosite_pal.c

00001 /*****************************************************************************
00002 *
00003 *  exosite_hal.c - Exosite hardware & environmenat adapation layer.
00004 *  Copyright (C) 2014 Exosite LLC
00005 *
00006 *  Redistribution and use in source and binary forms, with or without
00007 *  modification, are permitted provided that the following conditions
00008 *  are met:
00009 *
00010 *    Redistributions of source code must retain the above copyright
00011 *    notice, this list of conditions and the following disclaimer.
00012 *
00013 *    Redistributions in binary form must reproduce the above copyright
00014 *    notice, this list of conditions and the following disclaimer in the
00015 *    documentation and/or other materials provided with the
00016 *    distribution.
00017 *
00018 *    Neither the name of Texas Instruments Incorporated nor the names of
00019 *    its contributors may be used to endorse or promote products derived
00020 *    from this software without specific prior written permission.
00021 *
00022 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00025 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00026 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00027 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00028 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00029 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00030 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00031 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00032 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 *
00034 *****************************************************************************/
00035 
00036 #include "exosite_pal.h"
00037 
00038 #define PAL_CIK_LENGTH 40
00039 
00040 static int exosock;
00041 
00042 static char exosite_pal_host[] = "coap.exosite.com";
00043 static char exosite_pal_port[] = "5683";
00044 
00045 int errno;
00046 
00047 /*!
00048  * \brief Creates a udp socket
00049  *
00050  * Ensures that the library has access to a client style UDP socket. This can
00051  * be done either through an OS, or direct calls to the modem.
00052  *
00053  * \return 0 if successful, else error code
00054  */
00055  uint8_t exopal_udp_sock()
00056  {
00057     // Socket to Exosite
00058     int rv;
00059 
00060     struct addrinfo exohints, *servinfo, *q;
00061 
00062     memset(&exohints, 0, sizeof exohints);
00063     exohints.ai_family = AF_UNSPEC;
00064     exohints.ai_socktype = SOCK_DGRAM;
00065     exohints.ai_flags = AI_PASSIVE;
00066 
00067     if ((rv = getaddrinfo(exosite_pal_host, exosite_pal_port, &exohints, &servinfo)) != 0) {
00068         fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
00069         return 1;
00070     }
00071 
00072     // loop through all the results and make a socket
00073     for(q = servinfo; q != NULL; q = q->ai_next) {
00074         if ((exosock = socket(q->ai_family, q->ai_socktype, q->ai_protocol)) == -1) {
00075             perror("Socket Call Failed");
00076             continue;
00077         }
00078 
00079         fcntl(exosock, F_SETFL, O_NONBLOCK);
00080 
00081         break;
00082     }
00083 
00084     if (q == NULL) {
00085         fprintf(stderr, "Failed to Bind Socket\n");
00086         return 2;
00087     }
00088 
00089     if (connect(exosock, q->ai_addr, q->ai_addrlen) == -1)
00090         return 3;
00091 
00092     return 0;
00093 }
00094 
00095 
00096 /*!
00097  * \brief
00098  *
00099  * Any HW or SW initialization should be performed in here
00100  *
00101  * This function is meant to perform any one time initialization and/or setup.
00102  * This will be called every time Exosite_init is called.
00103  *
00104  */
00105 uint8_t exopal_init()
00106 {
00107     return 0;
00108 }
00109 
00110 /*!
00111  * \brief Sends a UDP Packet to Exosite
00112  *
00113  * Write data out to the currently open socket
00114  *
00115  * \param[in] buffer Data to write to socket
00116  * \param[in] len Length of data to write to socket
00117  *
00118  * \sa exopal_socketRead
00119  *
00120  * \return 0 if successful, else error code
00121  */
00122 uint8_t exopal_udp_send(const uint8_t *buf, size_t len)
00123 {
00124     size_t bytes_sent;
00125     if ((bytes_sent = send(exosock, buf, len, 0)) == -1){
00126         fprintf(stderr, "Socket SEND Error: %s\n", strerror(errno));
00127         return 1;
00128     }
00129 
00130     return 0;
00131 }
00132 
00133 /*!
00134  * \brief Receives a Packet from Exosite
00135  *
00136  * \param[in] bufferSize Size of buffer
00137  * \param[out] buf Buffer received data will be written to
00138  * \param[out] rlen amount of data received from modem
00139  *
00140  *
00141  * \sa exopal_socketWrite
00142  *
00143  * \note This function should not block, it should return immediately if there
00144  *       are no waiting UDP packets.
00145  *
00146  * \return 0 if successful, else error code
00147  */
00148 uint8_t exopal_udp_recv(uint8_t *buf, size_t size, size_t *rlen)
00149 {
00150     ssize_t bytes_recv;
00151     bytes_recv = recv(exosock, buf, size, 0);
00152     if (bytes_recv < 0) {
00153         if (errno != EAGAIN){
00154             fprintf(stderr, "Socket RECV Error: %s\n", strerror(errno));
00155             return 1;
00156         } else {
00157             return 2;
00158         }
00159     }
00160 
00161     *rlen = bytes_recv;
00162 
00163     return 0;
00164 }
00165 
00166 /*!
00167  * \brief Stores the cik in non-volatile storage.
00168  *
00169  * \param[in] cik pointer to a buffer containing 40 char CIK.
00170  *
00171  * \return 0 if successful, else error code
00172  */
00173 uint8_t exopal_store_cik(const char *cik)
00174 {
00175     size_t bytes_written;
00176     FILE *file;
00177     file = fopen("cik", "w");
00178 
00179     if (file == NULL)
00180         return 2;
00181     
00182     bytes_written = fwrite(cik, sizeof(char), 40, file);
00183 
00184     if (bytes_written != 40)
00185         return 1;
00186 
00187 
00188     fclose(file);
00189 
00190     return 0;
00191 }
00192 
00193 
00194 /*!
00195  * \brief Retrieves the cik from non-volatile storage.
00196  *
00197  * \param[out] pointer to 40 byte buffer into which you put the CIK.
00198  *
00199  * \return 0 if successful , 1 if no CIK has been saved, >1 if fatal error
00200  */
00201 uint8_t exopal_retrieve_cik(char *cik)
00202 {
00203     size_t bytes_read;
00204     FILE *file;
00205     file = fopen("cik", "r");
00206 
00207     if (file == NULL)
00208         return 2;
00209     
00210     bytes_read = fread(cik, sizeof(char), 40, file);
00211 
00212     if (bytes_read != 40)
00213         return 1;
00214 
00215     fclose(file);
00216 
00217     return 0;
00218 }
00219 
00220 
00221 uint64_t exopal_get_time()
00222 {
00223     struct timeval tv;
00224     gettimeofday(&tv,NULL);
00225     return tv.tv_sec * (uint64_t)1000000 + tv.tv_usec;
00226 }
00227 
00228 void exopal_set_time(uint64_t timestamp_us)
00229 {
00230     return;
00231 }