[PATCH 2/2] osmocon: Option -a runs program/script on upload

Christian Vogel vogelchr at vogel.cx
Sun Feb 5 13:33:26 UTC 2012


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--




More information about the baseband-devel mailing list