Satellite Observers Workbench. NOT yet complete, just published for forum posters to \"cherry pick\" pieces of code as requiered as an example.
pccomms/handlers/mode1.c@0:0a841b89d614, 2010-10-11 (annotated)
- Committer:
- AjK
- Date:
- Mon Oct 11 10:34:55 2010 +0000
- Revision:
- 0:0a841b89d614
Totally Alpha quality as this project isn\t completed. Just publishing it as it answers many questions asked in the forums
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AjK | 0:0a841b89d614 | 1 | /**************************************************************************** |
AjK | 0:0a841b89d614 | 2 | * Copyright 2010 Andy Kirkham, Stellar Technologies Ltd |
AjK | 0:0a841b89d614 | 3 | * |
AjK | 0:0a841b89d614 | 4 | * This file is part of the Satellite Observers Workbench (SOWB). |
AjK | 0:0a841b89d614 | 5 | * |
AjK | 0:0a841b89d614 | 6 | * SOWB is free software: you can redistribute it and/or modify |
AjK | 0:0a841b89d614 | 7 | * it under the terms of the GNU General Public License as published by |
AjK | 0:0a841b89d614 | 8 | * the Free Software Foundation, either version 3 of the License, or |
AjK | 0:0a841b89d614 | 9 | * (at your option) any later version. |
AjK | 0:0a841b89d614 | 10 | * |
AjK | 0:0a841b89d614 | 11 | * SOWB is distributed in the hope that it will be useful, |
AjK | 0:0a841b89d614 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
AjK | 0:0a841b89d614 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
AjK | 0:0a841b89d614 | 14 | * GNU General Public License for more details. |
AjK | 0:0a841b89d614 | 15 | * |
AjK | 0:0a841b89d614 | 16 | * You should have received a copy of the GNU General Public License |
AjK | 0:0a841b89d614 | 17 | * along with SOWB. If not, see <http://www.gnu.org/licenses/>. |
AjK | 0:0a841b89d614 | 18 | * |
AjK | 0:0a841b89d614 | 19 | * $Id: main.cpp 5 2010-07-12 20:51:11Z ajk $ |
AjK | 0:0a841b89d614 | 20 | * |
AjK | 0:0a841b89d614 | 21 | ***************************************************************************/ |
AjK | 0:0a841b89d614 | 22 | |
AjK | 0:0a841b89d614 | 23 | /* |
AjK | 0:0a841b89d614 | 24 | MODE 1 Packet handler. |
AjK | 0:0a841b89d614 | 25 | |
AjK | 0:0a841b89d614 | 26 | This mode is used by the Host to send a file containing all the TLEs that |
AjK | 0:0a841b89d614 | 27 | SOWB needs to aquire satellites. The base packet payload itself conatins |
AjK | 0:0a841b89d614 | 28 | a sub packet as defined below. Note, we assign a number of flash pages to |
AjK | 0:0a841b89d614 | 29 | the TLE file. Each flash page is 256bytes in size. So, the host sends the |
AjK | 0:0a841b89d614 | 30 | file in 256byte blocks. The sub-packet header defines the block being sent. |
AjK | 0:0a841b89d614 | 31 | We add to this block the flash base page and write the 256byte sub-packet |
AjK | 0:0a841b89d614 | 32 | payload into the flash device. Note, TLE files are ascii characters so the |
AjK | 0:0a841b89d614 | 33 | sub-packet payload is ASCII itself and doesn't require any conversions. |
AjK | 0:0a841b89d614 | 34 | |
AjK | 0:0a841b89d614 | 35 | Subp-acket format <BBBBCF>......... |
AjK | 0:0a841b89d614 | 36 | Where:- |
AjK | 0:0a841b89d614 | 37 | < is the "start of packet header" character. |
AjK | 0:0a841b89d614 | 38 | BBBB is a hex string representation of the uint16_t 256 char block. |
AjK | 0:0a841b89d614 | 39 | C is a two's complement checksum of the header from < to > inclusive. |
AjK | 0:0a841b89d614 | 40 | F is a char flag. Normally zero. |
AjK | 0:0a841b89d614 | 41 | > is the "end of packet header" character. |
AjK | 0:0a841b89d614 | 42 | .... is the packet payload, 256 bytes in length. |
AjK | 0:0a841b89d614 | 43 | |
AjK | 0:0a841b89d614 | 44 | */ |
AjK | 0:0a841b89d614 | 45 | |
AjK | 0:0a841b89d614 | 46 | #include "sowb.h" |
AjK | 0:0a841b89d614 | 47 | #include "user.h" |
AjK | 0:0a841b89d614 | 48 | #include "utils.h" |
AjK | 0:0a841b89d614 | 49 | #include "flash.h" |
AjK | 0:0a841b89d614 | 50 | #include "pccomms.h" |
AjK | 0:0a841b89d614 | 51 | |
AjK | 0:0a841b89d614 | 52 | #define FLASH_BASE_TLE_FILE 10 |
AjK | 0:0a841b89d614 | 53 | |
AjK | 0:0a841b89d614 | 54 | /* Error flags to send back on failure. */ |
AjK | 0:0a841b89d614 | 55 | #define FLAG_BAD_CHECKSUM '1' |
AjK | 0:0a841b89d614 | 56 | #define FLAG_INVALID_LENGTH '2' |
AjK | 0:0a841b89d614 | 57 | |
AjK | 0:0a841b89d614 | 58 | /* Base packet payload to sub-packet header definition. */ |
AjK | 0:0a841b89d614 | 59 | typedef struct _pccomms_mode1_header { |
AjK | 0:0a841b89d614 | 60 | char lead_char; |
AjK | 0:0a841b89d614 | 61 | char block[4]; |
AjK | 0:0a841b89d614 | 62 | char csum; |
AjK | 0:0a841b89d614 | 63 | char flag; |
AjK | 0:0a841b89d614 | 64 | char trail_char; |
AjK | 0:0a841b89d614 | 65 | } PCCOMMS_MODE1_HEADER; |
AjK | 0:0a841b89d614 | 66 | |
AjK | 0:0a841b89d614 | 67 | /* Base packet payload to sub-packet overall definition. */ |
AjK | 0:0a841b89d614 | 68 | typedef struct _pccomms_mode1 { |
AjK | 0:0a841b89d614 | 69 | PCCOMMS_MODE1_HEADER header; |
AjK | 0:0a841b89d614 | 70 | char payload[256]; |
AjK | 0:0a841b89d614 | 71 | } PCCOMMS_MODE1; |
AjK | 0:0a841b89d614 | 72 | |
AjK | 0:0a841b89d614 | 73 | |
AjK | 0:0a841b89d614 | 74 | /** pccomms_mode1_failed |
AjK | 0:0a841b89d614 | 75 | * |
AjK | 0:0a841b89d614 | 76 | * Used to send back a failed packet with a flag "reason for failure". |
AjK | 0:0a841b89d614 | 77 | * |
AjK | 0:0a841b89d614 | 78 | * @param BASE_PACKET_A *a The original ASCII version of the packet header. |
AjK | 0:0a841b89d614 | 79 | * @param char flag The char flag to insert. |
AjK | 0:0a841b89d614 | 80 | */ |
AjK | 0:0a841b89d614 | 81 | void pccomms_mode1_failed(BASE_PACKET_A *a, char flag) { |
AjK | 0:0a841b89d614 | 82 | BASE_PACKET_A temp; |
AjK | 0:0a841b89d614 | 83 | char *p; |
AjK | 0:0a841b89d614 | 84 | int i; |
AjK | 0:0a841b89d614 | 85 | |
AjK | 0:0a841b89d614 | 86 | memcpy((char *)&temp, (char *)a, sizeof(BASE_PACKET_A)); |
AjK | 0:0a841b89d614 | 87 | temp.flag = flag; |
AjK | 0:0a841b89d614 | 88 | temp.csum = 0; |
AjK | 0:0a841b89d614 | 89 | temp.csum = strcsuml((char *)&temp, sizeof(BASE_PACKET_A)); |
AjK | 0:0a841b89d614 | 90 | for (p = (char *)&temp, i = 0; i < sizeof(BASE_PACKET_A); i++) { |
AjK | 0:0a841b89d614 | 91 | Uart3_putc((char)p[i]); |
AjK | 0:0a841b89d614 | 92 | } |
AjK | 0:0a841b89d614 | 93 | } |
AjK | 0:0a841b89d614 | 94 | |
AjK | 0:0a841b89d614 | 95 | /** pccomms_mode1_handler |
AjK | 0:0a841b89d614 | 96 | * |
AjK | 0:0a841b89d614 | 97 | * The packet handler for MODE 1. |
AjK | 0:0a841b89d614 | 98 | * |
AjK | 0:0a841b89d614 | 99 | * @param BASE_PACKET_B *b |
AjK | 0:0a841b89d614 | 100 | * @param BASE_PACKET_A *a |
AjK | 0:0a841b89d614 | 101 | * @return int |
AjK | 0:0a841b89d614 | 102 | */ |
AjK | 0:0a841b89d614 | 103 | int pccomms_mode1_handler(BASE_PACKET_B *b, BASE_PACKET_A *a) { |
AjK | 0:0a841b89d614 | 104 | PCCOMMS_MODE1 data; |
AjK | 0:0a841b89d614 | 105 | char *p; |
AjK | 0:0a841b89d614 | 106 | int page, c, i; |
AjK | 0:0a841b89d614 | 107 | |
AjK | 0:0a841b89d614 | 108 | /* Sanity check, should never fail, should really assert() */ |
AjK | 0:0a841b89d614 | 109 | if (b->mode != 1) return PCCOMMS_PACKET_REJECTED; |
AjK | 0:0a841b89d614 | 110 | |
AjK | 0:0a841b89d614 | 111 | /* Sanity check, should never fail, should really assert() */ |
AjK | 0:0a841b89d614 | 112 | if (b->length != sizeof(PCCOMMS_MODE1)) return PCCOMMS_PACKET_REJECTED; |
AjK | 0:0a841b89d614 | 113 | |
AjK | 0:0a841b89d614 | 114 | /* Copy the base packet payload into our internal data structure. */ |
AjK | 0:0a841b89d614 | 115 | for(p = (char *)&data, i = 0; i < sizeof(PCCOMMS_MODE1); i++) { |
AjK | 0:0a841b89d614 | 116 | c = Uart3_getc(0); |
AjK | 0:0a841b89d614 | 117 | if (c != -1) p[i] = (char)c; |
AjK | 0:0a841b89d614 | 118 | else { |
AjK | 0:0a841b89d614 | 119 | /* This shouldn't happen as once the IRQ system has detected the |
AjK | 0:0a841b89d614 | 120 | end of the packet it no longer inserts serial chars into the |
AjK | 0:0a841b89d614 | 121 | buffer. So another sanity check really. Unless the Host did |
AjK | 0:0a841b89d614 | 122 | in fact screw up somewhere. */ |
AjK | 0:0a841b89d614 | 123 | pccomms_mode1_failed(a, FLAG_INVALID_LENGTH); |
AjK | 0:0a841b89d614 | 124 | return PCCOMMS_PACKET_REJECTED; |
AjK | 0:0a841b89d614 | 125 | } |
AjK | 0:0a841b89d614 | 126 | } |
AjK | 0:0a841b89d614 | 127 | |
AjK | 0:0a841b89d614 | 128 | /* Run a checksum check. On failure, send back the Host's packet with "flag" set to "bad checksum". */ |
AjK | 0:0a841b89d614 | 129 | if (strsuml((char *)&data, sizeof(PCCOMMS_MODE1)) != 0) { |
AjK | 0:0a841b89d614 | 130 | pccomms_mode1_failed(a, FLAG_BAD_CHECKSUM); |
AjK | 0:0a841b89d614 | 131 | return PCCOMMS_PACKET_REJECTED; |
AjK | 0:0a841b89d614 | 132 | } |
AjK | 0:0a841b89d614 | 133 | |
AjK | 0:0a841b89d614 | 134 | /* Get the block header and add the flash page offset. */ |
AjK | 0:0a841b89d614 | 135 | page = (int)hex2bin(data.header.block, 4) + FLASH_BASE_TLE_FILE; |
AjK | 0:0a841b89d614 | 136 | |
AjK | 0:0a841b89d614 | 137 | /* Assuming we programmed the flash device ok, return packet accepted. */ |
AjK | 0:0a841b89d614 | 138 | flash_page_write(page, data.payload); |
AjK | 0:0a841b89d614 | 139 | while(flash_write_in_progress()) user_call_process(); |
AjK | 0:0a841b89d614 | 140 | return PCCOMMS_PACKET_ACCEPTED; |
AjK | 0:0a841b89d614 | 141 | } |
AjK | 0:0a841b89d614 | 142 |