The program option "-a program" runs the specified program or
script after a ACK from the phone has been received. This can be used
to trigger uploading the second-stage firmware with osmoload after
the osmocom loader has successfully been run on the phone.
---
src/host/osmocon/osmocon.c | 76 ++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 74 insertions(+), 2 deletions(-)
diff --git a/src/host/osmocon/osmocon.c b/src/host/osmocon/osmocon.c
index b3eaedb..eefbed2 100644
--- a/src/host/osmocon/osmocon.c
+++ b/src/host/osmocon/osmocon.c
@@ -30,6 +30,7 @@
#include <stdint.h>
#include <fcntl.h>
#include <errno.h>
+#include <signal.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/types.h>
@@ -178,6 +179,19 @@ struct dnload {
static struct dnload dnload;
static struct osmo_timer_list tick_timer;
+/* Information needed for callback on successful program upload to mobile.
+ * Only active if ack_prog_info.progname != NULL. */
+
+#define ACK_PROG_TIMER_DELAY 2000000
+static struct osmo_timer_list ack_prog_timer;
+struct ack_prog_info {
+ char *progname;
+ char *sockname;
+ char *serialdev;
+ char * const *envp;
+};
+static struct ack_prog_info ack_prog_info = { NULL };
+
/* Compal ramloader specific */
static const uint8_t phone_prompt1[] = { 0x1b, 0xf6, 0x02, 0x00, 0x41, 0x01, 0x40 };
static const uint8_t dnload_cmd[] = { 0x1b, 0xf6, 0x02, 0x00, 0x52, 0x01, 0x53 };
@@ -823,6 +837,9 @@ static int handle_read(void)
dnload.write_ptr = dnload.data;
dnload.expect_hdlc = 1;
+ if(ack_prog_info.progname)
+ osmo_timer_schedule(&ack_prog_timer,0,ACK_PROG_TIMER_DELAY);
+
/* check for romloader chainloading mode used as a workaround
* for the magic on the C139/C140 and J100i */
if (dnload.chainload_filename != NULL) {
@@ -1202,6 +1219,7 @@ dnload_mode_to_str(enum dnload_mode mode){
"\t\t [ -m {c123,c123xor,c140,c140xor,c155,romload,mtk} ]\n" \
"\t\t [ -c /to-be-chainloaded-file.bin ]\n" \
"\t\t [ -i beacon-interval (mS) ]\n" \
+ "\t\t [ -a program-to-be-run-after-upload-ack ]\n" \
"\t\t file.bin\n\n" \
"* Open serial port /dev/ttyXXXX (connected to your phone)\n" \
"* Perform handshaking with the ramloader in the phone\n" \
@@ -1401,7 +1419,46 @@ void parse_debug(const char *str)
}
}
-int main(int argc, char **argv)
+/* timer callback function that gets triggered after ACK
+ * for successful program upload has been received from the phone
+ */
+
+void
+ack_prog_callback(void *p)
+{
+ pid_t chld;
+ char *argv[]={
+ ack_prog_info.progname,
+ ack_prog_info.sockname,
+ ack_prog_info.serialdev,
+ (char*)dnload_mode_str[dnload.mode],
+ dnload.filename,
+ NULL
+ };
+ int i;
+
+ signal(SIGCHLD,SIG_IGN);
+
+ if((chld=fork()) != 0){ /* ---- in parent ---- */
+ if(chld == -1)
+ perror("fork()");
+ else
+ fprintf(stderr,"Running %s on ack.\n",
+ ack_prog_info.progname);
+ return;
+ };
+
+ /* ---- in child ---- */
+ for(i=3;i<1024;i++)
+ close(i);
+
+ execve(ack_prog_info.progname,argv,ack_prog_info.envp);
+ perror(ack_prog_info.progname);
+ exit(1);
+}
+
+int
+main(int argc, char **argv,char **envp)
{
int opt, flags;
uint32_t tmp_load_address = ROMLOAD_ADDRESS;
@@ -1414,7 +1471,7 @@ int main(int argc, char **argv)
dnload.previous_filename = NULL;
dnload.beacon_interval = DEFAULT_BEACON_INTERVAL;
- while ((opt = getopt(argc, argv, "d:hl:p:m:c:s:i:v")) != -1) {
+ while ((opt = getopt(argc, argv, "d:hl:p:m:c:s:i:va:")) != -1) {
switch (opt) {
case 'p':
serial_dev = optarg;
@@ -1444,6 +1501,9 @@ int main(int argc, char **argv)
case 'i':
dnload.beacon_interval = atoi(optarg) * 1000;
break;
+ case 'a':
+ ack_prog_info.progname = optarg;
+ break;
case 'h':
default:
usage(argv[0]);
@@ -1451,12 +1511,23 @@ int main(int argc, char **argv)
}
}
+
if (argc <= optind) {
dnload.filename = NULL;
} else {
dnload.filename = argv[optind];
}
+ if(ack_prog_info.progname){
+ fprintf(stderr,"Will run %s on successful upload.\n",
+ ack_prog_info.progname);
+ ack_prog_info.sockname = (char*)loader_un_path;
+ ack_prog_info.serialdev = serial_dev;
+ ack_prog_info.envp = envp;
+ ack_prog_timer.cb = ack_prog_callback;
+ ack_prog_timer.data = &ack_prog_info;
+ }
+
dnload.serial_fd.fd = osmo_serial_init(serial_dev, MODEM_BAUDRATE);
if (dnload.serial_fd.fd < 0) {
fprintf(stderr, "Cannot open serial device %s\n", serial_dev);
@@ -1520,3 +1591,4 @@ int main(int argc, char **argv)
exit(0);
}
+
--
1.7.0.4
--X1bOJ3K7DJ5YkBrT
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="osmoload_sh.txt"
#!/bin/bash
socket="$1"
port="$2"
method="$3"
main_fw="$4"
fw_dir="${main_fw%/*}"
new_fw="${fw_dir}/rssi.highram.bin"
osmoload="$OSMOCOM_ROOT/osmocom-bb/src/host/osmocon/osmoload"
tag="[${0##*/}]"
echo "Environment:"
env
if ! [ -x "$osmoload" ] ; then
echo "$tag *** $osmoload not found/not executable." >&2
exit 1
fi
if ! [ -f "$new_fw" ] ; then
echo "$tag *** $new_fw not found." >&2
exit 1
fi
echo "$tag Socket is $socket, port is $port." >&2
echo "$tag Loader method was $method." >&2
echo "$tag New firmware will be $new_fw." >&2
MAX_PINGS=5
N=0
while [ "$N" -lt "$MAX_PINGS" ] ; do
N="$(( $N + 1 ))"
$osmoload -l $socket ping
if [ "$?" == 0 ] ; then
break
fi
done
if [ "$N" -ge $MAX_PINGS ] ; then
echo "$tag *** could not ping phone!" >&2
exit 1
fi
$osmoload -l $socket memload 0x820000 $new_fw
if [ "$?" != 0 ] ; then
echo "$tag *** could not upload firmware!" >&2
exit 1
fi
$osmoload -l $socket jump 0x820000
if [ "$?" != 0 ] ; then
echo "$tag *** could not run firmware!" >&2
exit 1
fi
--X1bOJ3K7DJ5YkBrT--