📄 mmihomezone.c
字号:
if (data->received==HZ_RECEIVED_HZ_OFF)
return;
TRACE_FUNCTION("homezoneActivateCB()");
/* Check table to see if correct channel is included */
stopSearch = FALSE;
emptyID = 0xFFFF;
for (index=0; index<MAX_MIDS && !stopSearch; index++)
{
TRACE_EVENT_P2("Mid %d is %X", index, g_smscb_data.CBTopics.entry[index].msg_id);
if (g_smscb_data.CBTopics.entry[index].msg_id==HZ_IDENTIFIER)
{
stopSearch = TRUE;
}
else if (g_smscb_data.CBTopics.entry[index].msg_id==NO_MID)
{
emptyID = index;
stopSearch = TRUE;
}
}
TRACE_EVENT_P1("Emtpy ID %d", emptyID);
if (emptyID!=0xFFFF && emptyID<MAX_MIDS-1)
{
strncpy (g_smscb_data.CBTopics.entry[emptyID].name, HZ_CB_NAME, CB_TAG_LENGTH);
g_smscb_data.CBTopics.entry[emptyID].msg_id = HZ_IDENTIFIER;
g_smscb_data.CBTopics.entry[emptyID].dcs = 0;
// add a new entry
emptyID += 1;
g_smscb_data.CBTopics.length = emptyID;
}
smscb_setCBsettings(SMSCB_SWITCH_ON);
/*
sms_set_mt_ind(SMSCB_SWITCH_ON);
*/
return;
}
/*******************************************************************************
$Function: homezoneCBData
$Description: A cell broadcast message has been received, containing information about
the location of the current cell
$Returns: None.
$Arguments: message - The text of the cell broadcast message
*******************************************************************************/
void homezoneCBData(char *message)
{
T_homezone_data *data = &homezoneData;
/* Check if homezone is already switched off */
if (data->received==HZ_RECEIVED_HZ_OFF)
return;
TRACE_FUNCTION("homezoneCellData()");
/* Calculate the current position from the text of the message */
data->current_X = calculateDecimal( &message[0], HZ_COORD_DIGITS );
data->current_Y = calculateDecimal( &message[HZ_COORD_DIGITS], HZ_COORD_DIGITS );
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT_P2("current_X: %X, current_Y: %X", data->current_X, data->current_Y);
#endif
data->received |= HZ_RECEIVED_CB; // We now have received cell broadcast message.
/* SPR877 - SH - now only call HZ algorithm if a cell res has recently taken place */
if (data->received==HZ_RECEIVED_ALL && data->new_cell_res) // If we've received everything, call algorithm.
{
homezoneLocate();
data->new_cell_res = FALSE;
}
return;
}
/*******************************************************************************
$Function: homezoneLocate
$Description: Looks at coordinates from cell broadcast message and calculates if
they are in a homezone
$Returns: None
$Arguments: None
*******************************************************************************/
void homezoneLocate()
{
T_homezone_data *data = &homezoneData;
T_homezone *homezone = data->homezone;
long deltaX;
long deltaY;
USHORT hzIndex;
USHORT cacheIndex;
U32 Dsquared;
BOOL foundInCache;
USHORT cacheFreeSpace;
USHORT field;
USHORT record;
/* Check if homezone is already switched off */
if (data->received==HZ_RECEIVED_HZ_OFF)
return;
TRACE_FUNCTION("homezoneLocate()");
data->current_zone = HZ_NOT_IN_ZONE; // We don't know if we're in a homezone yet (homezones = 0 to 3)
field = HZ_NOT_IN_ZONE; // The cache to update
/* Work out if we're in a homezone using current_X and current_Y, received from CB message */
if (data->received == HZ_RECEIVED_ALL)
{
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT_P2("Current cell X: %X, Y: %X", data->current_X,data->current_Y);
#endif
/* Check to see if (current_X,current_Y) is in any of the defined homezones */
for (hzIndex=0; hzIndex<HZ_ZONES_MAX && data->current_zone==HZ_NOT_IN_ZONE; hzIndex++) // For each homezone...
{
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT_P1("Homezone %d...", hzIndex);
TRACE_EVENT_P3("Has coords X: %X, Y: %X, R2: %X", homezone[hzIndex].X, homezone[hzIndex].Y, homezone[hzIndex].Rsquared);
#endif
if (homezone[hzIndex].active) // Provided the homezone is active
{
#ifdef TRACE_MMIHOMEZONE // Calculate X and Y distance
TRACE_EVENT("Is active.");
#endif
deltaX = labs(data->current_X-homezone[hzIndex].X); // between centre of current cell
deltaY = labs(data->current_Y-homezone[hzIndex].Y); // and centre of the homezone
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT_P1("deltaX = %d",deltaX);
TRACE_EVENT_P1("deltaY = %d",deltaY);
#endif
if (deltaX<=HZ_DISTANCE_MAX && deltaY<=HZ_DISTANCE_MAX) // If not too far...
{
Dsquared = deltaX*deltaX+deltaY*deltaY; // Calculate the resultant distance squared
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT_P1("Dsquared = %d",Dsquared);
#endif
if (Dsquared <= homezone[hzIndex].Rsquared) // If within radius of homezone squared
{
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT("Contains the current cell.");
#endif
data->current_zone = hzIndex; // Current zone is this homezone
if (!homezone[hzIndex].cityzone) // Then: if it's not a cityzone
{
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT("Is not a cityzone.");
#endif
foundInCache = FALSE; // Look through the cache for this
cacheFreeSpace = HZ_CACHE_MAX; // homezone to see if cell is listed
for (cacheIndex=0; cacheIndex<HZ_CACHE_MAX && !foundInCache; cacheIndex++)
{
if (data->cid==homezone[hzIndex].cid[cacheIndex])
{
foundInCache = TRUE; // We've found it!
}
if (homezone[hzIndex].cid[cacheIndex]==0 && cacheFreeSpace==HZ_CACHE_MAX)
cacheFreeSpace = cacheIndex; // Or we've found an empty space
}
if (!foundInCache) // If not there, need to add it
{
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT("Is not in the cache.");
#endif
if (cacheFreeSpace==HZ_CACHE_MAX) // If we didn't find a free space...
{
cacheFreeSpace = rand() % HZ_CACHE_MAX; // Choose a random entry
}
homezone[hzIndex].cid[cacheFreeSpace] = data->cid; // And store current cell there
homezone[hzIndex].lac[cacheFreeSpace] = data->lac; // with its location area code
field = hzIndex+HZ_SIM_CELL_CACHE; // We've changed the cache
record = cacheFreeSpace+1;
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT_P1("Have added to cache, entry %d.",cacheFreeSpace);
#endif
}
}
}
else // If we're not in the homezone...
{
foundInCache = FALSE; // Look through the cache for this
// homezone to see if cell is listed
for (cacheIndex=0; cacheIndex<HZ_CACHE_MAX && !foundInCache; cacheIndex++)
{
if (data->cid==homezone[hzIndex].cid[cacheIndex])
{
foundInCache = TRUE; // We've found it!
cacheFreeSpace = cacheIndex; // Record where it is
break;
}
}
if (foundInCache) // If it's there...
{
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT("Is in the cache and shouldn't be.");
#endif
homezone[hzIndex].cid[cacheFreeSpace] = 0; // ...remove it
field = hzIndex+HZ_SIM_CELL_CACHE; // We've changed the cache
record = cacheFreeSpace+1;
data->current_zone = HZ_NOT_IN_ZONE; // We're not in this zone
}
#ifdef TRACE_MMIHOMEZONE
else
{
TRACE_EVENT("Isn't in the cache and shouldn't be.");
}
#endif
}
/* Replace oldest cell in dynamic cache with new cell */
data->recent_cell_index++;
if (data->recent_cell_index>=HZ_RECENT_MAX)
data->recent_cell_index = 0;
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT_P1("Adding to recent list, index = %d", data->recent_cell_index);
#endif
data->recent_cell[data->recent_cell_index] = data->cid;
data->recent_cell_zone[data->recent_cell_index] = data->current_zone;
#ifdef TRACE_MMIHOMEZONE
for (cacheIndex = 0; cacheIndex<HZ_RECENT_MAX; cacheIndex++)
{
TRACE_EVENT_P3("Recent cache %d: CID %X, zone %X",cacheIndex, data->recent_cell[cacheIndex], data->recent_cell_zone[cacheIndex]);
}
#endif
}
}
}
}
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT("CACHES AFTER UPDATE");
for (hzIndex=0; hzIndex<HZ_ZONES_MAX; hzIndex++) // For each homezone...
{
TRACE_EVENT_P2("Zone %d (%s)", hzIndex, homezone[hzIndex].Tag);
if (homezone[hzIndex].active && !homezone[hzIndex].cityzone) // If it's active, and not a cityzone
{
for (cacheIndex=0; cacheIndex<HZ_CACHE_MAX; cacheIndex++) // Check the cache.
{
TRACE_EVENT_P3("Cache %d: lac %X, cid %X", cacheIndex, homezone[hzIndex].lac[cacheIndex], homezone[hzIndex].cid[cacheIndex]);
}
}
}
#endif
/* Update icon/text tag. */
homezoneUpdateDisplay();
/* Write data back to SIM if cache has changed & SIM files present */
if (field!=HZ_NOT_IN_ZONE && (data->received & HZ_RECEIVED_SIMDATA))
{
homezoneWriteSim(field, record);
}
return;
}
/*******************************************************************************
$Function: homezoneUpdate
$Description: Main homezone function; check whether MS is in a homezone or not
$Returns:
$Arguments: lac - the location area code of the current cell (on cell reselection)
cid - the ID of the current cell (on cell reselection)
*******************************************************************************/
void homezoneUpdate(USHORT lac, USHORT cid)
{
T_homezone_data *data = &homezoneData;
T_homezone *homezone = data->homezone;
USHORT hzIndex;
USHORT cacheIndex;
UBYTE cacheUpdate;
UBYTE recordUpdate;
TRACE_FUNCTION("homezoneUpdate()");
data->current_zone = HZ_NOT_IN_ZONE; // We don't know if we're in a homezone yet (homezones = 0 to 3)
data->received |= HZ_RECEIVED_CELLRES; // Have received this event
data->lac = lac;
data->cid = cid;
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT_P3("lac: %X, cid: %X, received: %d", lac, cid, data->received);
#endif
/* If either are zero or -1, the reselection data is invalid */
if ((lac==0 || cid==0) || (lac==0xFFFF || cid==0xFFFF))
{
data->received &= (~HZ_RECEIVED_CELLRES);
homezoneUpdateDisplay();
return;
}
data->new_cell_res = TRUE; // Cell res just occurred
/* Must have received SIM data to continue*/
if (!(data->received & HZ_RECEIVED_SIMDATA))
return;
/* Check homezone cache for each homezone */
/* Can do this even if we haven't received the CB message */
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT("Checking zone caches...");
#endif
for (hzIndex=0; hzIndex<HZ_ZONES_MAX && data->current_zone==HZ_NOT_IN_ZONE; hzIndex++) // For each homezone...
{
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT_P2("Zone %d (%s)", hzIndex, homezone[hzIndex].Tag);
#endif
if (homezone[hzIndex].active && !homezone[hzIndex].cityzone) // If it's active, and not a cityzone
{
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT("Is Active.");
#endif
for (cacheIndex=0; cacheIndex<HZ_CACHE_MAX && data->current_zone==HZ_NOT_IN_ZONE; cacheIndex++) // Check the cache.
{
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT_P3("Cache %d: lac %X, cid %X", cacheIndex, homezone[hzIndex].lac[cacheIndex], homezone[hzIndex].cid[cacheIndex]);
#endif
if (cid==homezone[hzIndex].cid[cacheIndex]) // If the current cell is in the cache....
{
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT_P1("Cell found in cache %d.",cacheIndex);
#endif
data->current_zone = hzIndex; // Then this is our current homezone!
}
}
}
}
/* If we didn't find a homezone, check recent cells cache to see if we're in a cityzone */
for (cacheIndex=0; cacheIndex<HZ_RECENT_MAX && data->current_zone==HZ_NOT_IN_ZONE; cacheIndex++) // For each recent cell...
{
if (cid==data->recent_cell[cacheIndex] && data->recent_cell_zone[cacheIndex]!=HZ_NOT_IN_ZONE) // If we're in that cell & it's in a cityzone
{
if (homezone[data->recent_cell_zone[cacheIndex]].cityzone
&& homezone[data->recent_cell_zone[cacheIndex]].active) // Make sure the cityzone is active
{
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT_P1("FOUND cityzone in recent cache %d",cacheIndex);
#endif
data->current_zone = data->recent_cell_zone[cacheIndex]; // and this is our current cityzone
}
}
}
homezoneUpdateDisplay(); // Update icon/text tag.
return;
}
/*******************************************************************************
$Function: homezoneUpdateDisplay
$Description:
$Returns: Updates the homezone icon and text string appropriately
$Arguments: none
*******************************************************************************/
void homezoneUpdateDisplay(void)
{
T_homezone_data *data = &homezoneData;
TRACE_FUNCTION("homezoneUpdateDisplay()");
iconsDeleteState(iconIdHomezone);
addSatMessage(NULL);
if (data->current_zone!=HZ_NOT_IN_ZONE) // If not in a homezone, leave blank
{
addSatMessage(data->homezone[data->current_zone].Tag);
if (!data->homezone[data->current_zone].cityzone) // Display icon if homezone rather than cityzone
{
iconsSetState(iconIdHomezone);
}
}
return;
}
/*******************************************************************************
$Function: calculateDecimal
$Description:
$Returns: Returns a decimal number from a string of ascii digits
$Arguments: none
*******************************************************************************/
static U32 calculateDecimal( char *string, int length )
{
U32 total = 0;
int index;
/* decode each decimal character in turn */
for (index = 0; index < length; index++ )
{
if (string[index]>='0' && string[index]<='9')
{
total = ( total * 10 ) + ( string[index] - '0' );
}
}
return total;
}
/*******************************************************************************
$Function: readHexFromSimfile
$Description: Reads a hex string (MSB first) from a sim file
$Returns: The hex number
$Arguments: simFile - the point in the simFile at which the string occurs
length - the length of the string
*******************************************************************************/
static U32 readHexFromSimfile( UBYTE *simFile, int length )
{
U32 total = 0;
int index;
for ( index = 0; index < length; index++ )
{
total = ( total << 8 ) + simFile[index];
}
return total;
}
/*******************************************************************************
$Function: writeHexToSimfile
$Description: Writes a hex string (MSB first) to a sim file
$Returns: None
$Arguments: simFile - the point in the simFile at which the string occurs
length - the length of the string
*******************************************************************************/
static void writeHexToSimfile( UBYTE *simFile, U32 value, int length )
{
int index;
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT_P1("Hex of %X is:", value);
#endif
/* Note: '-1' below clarification:
* E.g. index=0, length=4: most significant byte is number shifted 3 bytes right. */
for ( index = 0; index < length; index++ )
{
simFile[index] = (value >> ((length-index-1)*8)) & 0xFF; /* SPR877 - SH - wrong before, added *8 */
#ifdef TRACE_MMIHOMEZONE
TRACE_EVENT_P2("Simfile %d is %X", index, simFile[index]);
#endif
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -