Satellite Observers Workbench. NOT yet complete, just published for forum posters to \"cherry pick\" pieces of code as requiered as an example.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mode1.c Source File

mode1.c

00001 /****************************************************************************
00002  *    Copyright 2010 Andy Kirkham, Stellar Technologies Ltd
00003  *    
00004  *    This file is part of the Satellite Observers Workbench (SOWB).
00005  *
00006  *    SOWB is free software: you can redistribute it and/or modify
00007  *    it under the terms of the GNU General Public License as published by
00008  *    the Free Software Foundation, either version 3 of the License, or
00009  *    (at your option) any later version.
00010  *
00011  *    SOWB is distributed in the hope that it will be useful,
00012  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *    GNU General Public License for more details.
00015  *
00016  *    You should have received a copy of the GNU General Public License
00017  *    along with SOWB.  If not, see <http://www.gnu.org/licenses/>.
00018  *
00019  *    $Id: main.cpp 5 2010-07-12 20:51:11Z ajk $
00020  *    
00021  ***************************************************************************/
00022 
00023 /*
00024 MODE 1 Packet handler.
00025 
00026 This mode is used by the Host to send a file containing all the TLEs that
00027 SOWB needs to aquire satellites. The base packet payload itself conatins
00028 a sub packet as defined below. Note, we assign a number of flash pages to
00029 the TLE file. Each flash page is 256bytes in size. So, the host sends the
00030 file in 256byte blocks. The sub-packet header defines the block being sent.
00031 We add to this block the flash base page and write the 256byte sub-packet
00032 payload into the flash device. Note, TLE files are ascii characters so the
00033 sub-packet payload is ASCII itself and doesn't require any conversions.
00034 
00035 Subp-acket format   <BBBBCF>.........
00036 Where:-
00037     < is the "start of packet header" character.
00038     BBBB is a hex string representation of the uint16_t 256 char block.
00039     C is a two's complement checksum of the header from < to > inclusive.
00040     F is a char flag. Normally zero.
00041     > is the "end of packet header" character.
00042     .... is the packet payload, 256 bytes in length.
00043 
00044 */
00045 
00046 #include "sowb.h"
00047 #include "user.h"
00048 #include "utils.h"
00049 #include "flash.h"
00050 #include "pccomms.h"
00051 
00052 #define FLASH_BASE_TLE_FILE 10
00053 
00054 /* Error flags to send back on failure. */
00055 #define FLAG_BAD_CHECKSUM   '1'
00056 #define FLAG_INVALID_LENGTH '2'
00057 
00058 /* Base packet payload to sub-packet header definition. */
00059 typedef struct _pccomms_mode1_header {
00060     char        lead_char;
00061     char        block[4];
00062     char        csum;
00063     char        flag;
00064     char        trail_char;
00065 } PCCOMMS_MODE1_HEADER;
00066 
00067 /* Base packet payload to sub-packet overall definition. */
00068 typedef struct _pccomms_mode1 {
00069     PCCOMMS_MODE1_HEADER    header;
00070     char                    payload[256];
00071 } PCCOMMS_MODE1;
00072 
00073 
00074 /** pccomms_mode1_failed
00075  *
00076  * Used to send back a failed packet with a flag "reason for failure".
00077  *
00078  * @param BASE_PACKET_A *a The original ASCII version of the packet header.
00079  * @param char flag The char flag to insert. 
00080  */
00081 void pccomms_mode1_failed(BASE_PACKET_A *a, char flag) {
00082     BASE_PACKET_A temp;
00083     char *p;
00084     int i;
00085     
00086     memcpy((char *)&temp, (char *)a, sizeof(BASE_PACKET_A));
00087     temp.flag = flag;
00088     temp.csum = 0;
00089     temp.csum = strcsuml((char *)&temp, sizeof(BASE_PACKET_A));
00090     for (p = (char *)&temp, i = 0; i < sizeof(BASE_PACKET_A); i++) {
00091         Uart3_putc((char)p[i]);
00092     }
00093 }
00094 
00095 /** pccomms_mode1_handler
00096  *
00097  * The packet handler for MODE 1.
00098  *
00099  * @param BASE_PACKET_B *b
00100  * @param BASE_PACKET_A *a
00101  * @return int 
00102  */
00103 int pccomms_mode1_handler(BASE_PACKET_B *b, BASE_PACKET_A *a) {
00104     PCCOMMS_MODE1 data;
00105     char *p;
00106     int page, c, i;
00107         
00108     /* Sanity check, should never fail, should really assert() */    
00109     if (b->mode != 1) return PCCOMMS_PACKET_REJECTED;
00110     
00111     /* Sanity check, should never fail, should really assert() */    
00112     if (b->length != sizeof(PCCOMMS_MODE1)) return PCCOMMS_PACKET_REJECTED;
00113      
00114     /* Copy the base packet payload into our internal data structure. */
00115     for(p = (char *)&data, i = 0; i < sizeof(PCCOMMS_MODE1); i++) {
00116         c = Uart3_getc(0);
00117         if (c != -1) p[i] = (char)c;
00118         else {
00119             /* This shouldn't happen as once the IRQ system has detected the
00120                end of the packet it no longer inserts serial chars into the 
00121                buffer. So another sanity check really. Unless the Host did
00122                in fact screw up somewhere. */
00123             pccomms_mode1_failed(a, FLAG_INVALID_LENGTH);
00124             return PCCOMMS_PACKET_REJECTED;
00125         }
00126     }
00127 
00128     /* Run a checksum check. On failure, send back the Host's packet with "flag" set to "bad checksum". */
00129     if (strsuml((char *)&data, sizeof(PCCOMMS_MODE1)) != 0) {
00130         pccomms_mode1_failed(a, FLAG_BAD_CHECKSUM);
00131         return PCCOMMS_PACKET_REJECTED;
00132     }
00133     
00134     /* Get the block header and add the flash page offset. */
00135     page = (int)hex2bin(data.header.block, 4) + FLASH_BASE_TLE_FILE;    
00136     
00137     /* Assuming we programmed the flash device ok, return packet accepted. */    
00138     flash_page_write(page, data.payload);
00139     while(flash_write_in_progress()) user_call_process();
00140     return PCCOMMS_PACKET_ACCEPTED;
00141 }
00142