Roy Want / Mbed OS beaconCompileReadyFork
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers URLFrame.cpp Source File

URLFrame.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2015 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "URLFrame.h"
00018 
00019 /* CONSTRUCTOR */ 
00020 URLFrame::URLFrame(void)
00021 {
00022 }
00023     
00024 void URLFrame::setUnencodedUrlData(uint8_t* rawFrame, int8_t advTxPower, const char *rawUrl)
00025 {    
00026     uint8_t encodedUrl[ENCODED_BUF_SIZE];
00027     int encodedUrlLen = encodeURL(encodedUrl, rawUrl);
00028     encodedUrlLen = (encodedUrlLen > MAX_URL_DATA) ? MAX_URL_DATA : encodedUrlLen;
00029     setData(rawFrame, advTxPower, reinterpret_cast<const uint8_t*>(encodedUrl), encodedUrlLen);
00030 }
00031 
00032 void URLFrame::clearFrame(uint8_t* frame) {
00033     frame[FRAME_LEN_OFFSET] = 0; // Set frame length to zero to clear it
00034 }
00035 
00036 void URLFrame::setData(uint8_t* rawFrame, int8_t advTxPower, const uint8_t* encodedUrlData, uint8_t encodedUrlLen)
00037 {
00038     uint8_t index = 0;
00039     rawFrame[index++] = URL_HEADER_LEN + encodedUrlLen; // INDEX=0 = Frame Length = encodedURL size + 4 bytes of header below
00040     rawFrame[index++] = EDDYSTONE_UUID[0];              // FRAME 16-bit Eddystone UUID Low Byte (little endian)
00041     rawFrame[index++] = EDDYSTONE_UUID[1];              // FRAME 16-bit Eddystone UUID High Byte
00042     rawFrame[index++] = FRAME_TYPE_URL;                 // URL Frame Type
00043     rawFrame[index++] = advTxPower;                     // Power @ 0meter 
00044     
00045     memcpy(rawFrame + index, encodedUrlData, encodedUrlLen); 
00046 }
00047 
00048 uint8_t*  URLFrame::getData(uint8_t* rawFrame) {
00049     return &(rawFrame[URL_DATA_OFFSET]);
00050 }
00051 
00052 
00053 uint8_t  URLFrame::getDataLength(uint8_t* rawFrame) {
00054     return rawFrame[FRAME_LEN_OFFSET] - EDDYSTONE_UUID_LEN;
00055 }
00056 
00057 uint8_t* URLFrame::getAdvFrame(uint8_t* rawFrame) 
00058 {
00059     return &(rawFrame[ADV_FRAME_OFFSET]);
00060 }
00061 
00062 uint8_t URLFrame::getAdvFrameLength(uint8_t* rawFrame) 
00063 {
00064     return rawFrame[FRAME_LEN_OFFSET];
00065 }
00066 
00067 uint8_t* URLFrame::getEncodedUrl(uint8_t* rawFrame)
00068 {
00069     return &(rawFrame[URL_VALUE_OFFSET]);
00070 }
00071 
00072 uint8_t URLFrame::getEncodedUrlLength(uint8_t* rawFrame) 
00073 {
00074     return rawFrame[ADV_FRAME_OFFSET] - URL_HEADER_LEN;
00075 }
00076 
00077 
00078 uint8_t URLFrame::encodeURL(uint8_t* encodedUrl, const char *rawUrl)
00079 {
00080     uint8_t urlDataLength = 0;
00081     
00082     const char  *prefixes[] = {
00083         "http://www.",
00084         "https://www.",
00085         "http://",
00086         "https://",
00087     };
00088     const size_t NUM_PREFIXES = sizeof(prefixes) / sizeof(char *);
00089     const char  *suffixes[]   = {
00090         ".com/",
00091         ".org/",
00092         ".edu/",
00093         ".net/",
00094         ".info/",
00095         ".biz/",
00096         ".gov/",
00097         ".com",
00098         ".org",
00099         ".edu",
00100         ".net",
00101         ".info",
00102         ".biz",
00103         ".gov"
00104     };
00105     const size_t NUM_SUFFIXES = sizeof(suffixes) / sizeof(char *);
00106 
00107     memset(encodedUrl, 0, ENCODED_BUF_SIZE);
00108 
00109     if ((rawUrl == NULL) || (strlen(rawUrl) == 0)) {
00110         return urlDataLength;
00111     }
00112 
00113     /*
00114      * handle prefix
00115      */
00116     for (size_t i = 0; i < NUM_PREFIXES; i++) {
00117         size_t prefixLen = strlen(prefixes[i]);
00118         if (strncmp(rawUrl, prefixes[i], prefixLen) == 0) {
00119             encodedUrl[urlDataLength++]  = i;
00120             rawUrl                      += prefixLen;
00121             break;
00122         }
00123     }
00124 
00125     /*
00126      * handle suffixes
00127      */
00128     while (*rawUrl && (urlDataLength <= MAX_URL_DATA)) {
00129         /* check for suffix match */
00130         size_t i;
00131         for (i = 0; i < NUM_SUFFIXES; i++) {
00132             size_t suffixLen = strlen(suffixes[i]);
00133             if (strncmp(rawUrl, suffixes[i], suffixLen) == 0) {
00134                 encodedUrl[urlDataLength++]  = i;
00135                 rawUrl                      += suffixLen;
00136                 break; /* from the for loop for checking against suffixes */
00137             }
00138         }
00139         /* This is the default case where we've got an ordinary character which doesn't match a suffix. */
00140         if (i == NUM_SUFFIXES) {
00141             encodedUrl[urlDataLength++] = *rawUrl;
00142             ++rawUrl;
00143         }
00144     }
00145     return urlDataLength;
00146 }
00147 
00148 void URLFrame::setAdvTxPower(uint8_t* rawFrame, int8_t advTxPower)
00149 {
00150     rawFrame[URL_TXPOWER_OFFSET] = advTxPower;
00151 }